1.9.12~dfsg/0000755000000000000000000000000013214314510011340 5ustar rootroot1.9.12~dfsg/windows/0000755000000000000000000000000013244556535013054 5ustar rootroot1.9.12~dfsg/windows/JackWinNamedPipeNotifyChannel.cpp0000644000000000000000000000430113214314510021327 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackRequest.h" #include "JackWinNamedPipeNotifyChannel.h" #include "JackError.h" #include "JackConstants.h" namespace Jack { // Server to client int JackWinNamedPipeNotifyChannel::Open(const char* name) { jack_log("JackWinNamedPipeNotifyChannel::Open name = %s", name); // Connect to client listen pipe if (fNotifyPipe.Connect(jack_client_dir, name, 0) < 0) { jack_error("Cannot connect client pipe"); return -1; } // TODO : use a time out for notifications fNotifyPipe.SetReadTimeOut(SOCKET_TIME_OUT); return 0; } void JackWinNamedPipeNotifyChannel::Close() { jack_log("JackWinNamedPipeNotifyChannel::Close"); fNotifyPipe.Close(); } void JackWinNamedPipeNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) { JackClientNotification event(name, refnum, notify, sync, message, value1, value2); JackResult res; // Send notification if (event.Write(&fNotifyPipe) < 0) { jack_error("Could not write notification"); *result = -1; return; } // Read the result in "synchronous" mode only if (sync) { // Get result : use a time out if (res.Read(&fNotifyPipe) < 0) { jack_error("Could not read result"); *result = -1; } else { *result = res.fResult; } } else { *result = 0; } } } // end of namespace 1.9.12~dfsg/windows/JackAtomic_os.h0000644000000000000000000000342413214314510015714 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAtomic_WIN32__ #define __JackAtomic_WIN32__ #include "JackTypes.h" #ifndef __MINGW32__ #ifdef __SMP__ # define LOCK lock #else # define LOCK #endif #ifndef inline #define inline __inline #endif //---------------------------------------------------------------- // CAS functions //---------------------------------------------------------------- inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void * addr) { register char c; __asm { push ebx push esi mov esi, addr mov eax, value mov ebx, newvalue LOCK cmpxchg dword ptr [esi], ebx sete c pop esi pop ebx } return c; } #else #define LOCK "lock ; " static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) { register char ret; __asm__ __volatile__ ( "# CAS \n\t" LOCK "cmpxchg %2, (%1) \n\t" "sete %0 \n\t" : "=a" (ret) : "c" (addr), "d" (newvalue), "a" (value) ); return ret; } #endif #endif 1.9.12~dfsg/windows/JackWinNamedPipeServerChannel.h0000644000000000000000000000600213214314510020772 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinNamedPipeServerChannel__ #define __JackWinNamedPipeServerChannel__ #include "JackWinNamedPipe.h" #include "JackPlatformPlug.h" #include "JackConstants.h" #include "JackRequestDecoder.h" #include namespace Jack { class JackServer; class JackClientPipeThread : public JackRunnableInterface, public JackClientHandlerInterface { private: JackWinNamedPipeClient* fPipe; JackRequestDecoder* fDecoder; JackServer* fServer; JackThread fThread; int fRefNum; void ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult *res); void ClientRemove(detail::JackChannelTransactionInterface* socket, int refnum); void ClientKill(); static HANDLE fMutex; public: JackClientPipeThread(JackWinNamedPipeClient* pipe); virtual ~JackClientPipeThread(); int Open(JackServer* server); // Open the Server/Client connection void Close(); // Close the Server/Client connection // JackRunnableInterface interface bool Execute(); // To be used for find out if the object can be deleted bool IsRunning() { return (fRefNum >= 0); } }; /*! \brief JackServerChannel using pipe. */ class JackWinNamedPipeServerChannel : public JackRunnableInterface { private: JackWinNamedPipeServer fRequestListenPipe; // Pipe to create request socket for the client JackServer* fServer; JackThread fThread; // Thread to execute the event loop char fServerName[JACK_SERVER_NAME_SIZE+1]; std::list fClientList; void ClientAdd(JackWinNamedPipeClient* pipe); bool ClientListen(); bool ClientAccept(); public: JackWinNamedPipeServerChannel(); ~JackWinNamedPipeServerChannel(); int Open(const char* server_name, JackServer* server); // Open the Server/Client connection void Close(); // Close the Server/Client connection int Start(); void Stop(); // JackRunnableInterface interface bool Init(); bool Execute(); }; } // end of namespace #endif 1.9.12~dfsg/windows/JackNetWinSocket.cpp0000644000000000000000000003236513214314510016715 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackError.h" #include "JackNetWinSocket.h" namespace Jack { //utility ********************************************************************************************************* SERVER_EXPORT int GetHostName(char * name, int size) { if (gethostname(name, size) == SOCKET_ERROR) { jack_error("Can't get 'hostname' : %s", strerror(NET_ERROR_CODE)); strcpy(name, "default"); return -1; } return 0; } win_net_error_t NetErrorList[] = { E(0, "No error"), E(WSAEINTR, "Interrupted system call"), E(WSAEBADF, "Bad file number"), E(WSAEACCES, "Permission denied"), E(WSAEFAULT, "Bad address"), E(WSAEINVAL, "Invalid argument"), E(WSAEMFILE, "Too many open sockets"), E(WSAEWOULDBLOCK, "Operation would block"), E(WSAEINPROGRESS, "Operation now in progress"), E(WSAEALREADY, "Operation already in progress"), E(WSAENOTSOCK, "Socket operation on non-socket"), E(WSAEDESTADDRREQ, "Destination address required"), E(WSAEMSGSIZE, "Message too long"), E(WSAEPROTOTYPE, "Protocol wrong type for socket"), E(WSAENOPROTOOPT, "Bad protocol option"), E(WSAEPROTONOSUPPORT, "Protocol not supported"), E(WSAESOCKTNOSUPPORT, "Socket type not supported"), E(WSAEOPNOTSUPP, "Operation not supported on socket"), E(WSAEPFNOSUPPORT, "Protocol family not supported"), E(WSAEAFNOSUPPORT, "Address family not supported"), E(WSAEADDRINUSE, "Address already in use"), E(WSAEADDRNOTAVAIL, "Can't assign requested address"), E(WSAENETDOWN, "Network is down"), E(WSAENETUNREACH, "Network is unreachable"), E(WSAENETRESET, "Net connection reset"), E(WSAECONNABORTED, "Software caused connection abort"), E(WSAECONNRESET, "Connection reset by peer"), E(WSAENOBUFS, "No buffer space available"), E(WSAEISCONN, "Socket is already connected"), E(WSAENOTCONN, "Socket is not connected"), E(WSAESHUTDOWN, "Can't send after socket shutdown"), E(WSAETOOMANYREFS, "Too many references, can't splice"), E(WSAETIMEDOUT, "Connection timed out"), E(WSAECONNREFUSED, "Connection refused"), E(WSAELOOP, "Too many levels of symbolic links"), E(WSAENAMETOOLONG, "File name too long"), E(WSAEHOSTDOWN, "Host is down"), E(WSAEHOSTUNREACH, "No route to host"), E(WSAENOTEMPTY, "Directory not empty"), E(WSAEPROCLIM, "Too many processes"), E(WSAEUSERS, "Too many users"), E(WSAEDQUOT, "Disc quota exceeded"), E(WSAESTALE, "Stale NFS file handle"), E(WSAEREMOTE, "Too many levels of remote in path"), E(WSASYSNOTREADY, "Network system is unavailable"), E(WSAVERNOTSUPPORTED, "Winsock version out of range"), E(WSANOTINITIALISED, "WSAStartup not yet called"), E(WSAEDISCON, "Graceful shutdown in progress"), E(WSAHOST_NOT_FOUND, "Host not found"), E(WSANO_DATA, "No host data of that type was found"), { -1, NULL }, }; SERVER_EXPORT const char* PrintError(int error) { int i; for (i = 0; NetErrorList[i].code >= 0; ++i) { if (error == NetErrorList[i].code) return NetErrorList[i].msg; } return strerror(error); } //construct/destruct*********************************************************************************************** JackNetWinSocket::JackNetWinSocket() { fSockfd = 0; fSendAddr.sin_family = AF_INET; fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fRecvAddr.sin_zero, 0, 8); } JackNetWinSocket::JackNetWinSocket(const char* ip, int port) { fSockfd = 0; fPort = port; fSendAddr.sin_family = AF_INET; fSendAddr.sin_port = htons(port); fSendAddr.sin_addr.s_addr = inet_addr(ip); memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; fRecvAddr.sin_port = htons(port); fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fRecvAddr.sin_zero, 0, 8); } JackNetWinSocket::JackNetWinSocket(const JackNetWinSocket& socket) { fSockfd = 0; fPort = socket.fPort; fSendAddr = socket.fSendAddr; fRecvAddr = socket.fRecvAddr; } JackNetWinSocket::~JackNetWinSocket() { Close(); } JackNetWinSocket& JackNetWinSocket::operator=(const JackNetWinSocket& socket) { if (this != &socket) { fSockfd = 0; fPort = socket.fPort; fSendAddr = socket.fSendAddr; fRecvAddr = socket.fRecvAddr; } return *this; } //socket*********************************************************************************************************** int JackNetWinSocket::NewSocket() { if (fSockfd) { Close(); Reset(); } fSockfd = socket(AF_INET, SOCK_DGRAM, 0); return fSockfd; } bool JackNetWinSocket::IsLocal(char* ip) { if (strcmp(ip, "127.0.0.1") == 0) { return true; } char host_name[32]; gethostname(host_name, sizeof(host_name)); struct hostent* host = gethostbyname(host_name); if (host) { for (int i = 0; host->h_addr_list[i] != 0; ++i) { struct in_addr addr; memcpy(&addr, host->h_addr_list[i], sizeof(struct in_addr)); if (strcmp(inet_ntoa(addr), ip) == 0) { return true; } } return false; } else { return false; } } int JackNetWinSocket::Bind() { return bind(fSockfd, reinterpret_cast(&fRecvAddr), sizeof(SOCKADDR)); } int JackNetWinSocket::BindWith(const char* ip) { fRecvAddr.sin_addr.s_addr = inet_addr(ip); return Bind(); } int JackNetWinSocket::BindWith(int port) { fRecvAddr.sin_port = htons(port); return Bind(); } int JackNetWinSocket::Connect() { return connect(fSockfd, reinterpret_cast(&fSendAddr), sizeof(SOCKADDR)); } int JackNetWinSocket::ConnectTo(const char* ip) { fSendAddr.sin_addr.s_addr = inet_addr(ip); return Connect(); } void JackNetWinSocket::Close() { if (fSockfd) closesocket(fSockfd); fSockfd = 0; } void JackNetWinSocket::Reset() { fSendAddr.sin_family = AF_INET; fSendAddr.sin_port = htons(fPort); fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; fRecvAddr.sin_port = htons(fPort); fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fRecvAddr.sin_zero, 0, 8); } bool JackNetWinSocket::IsSocket() { return(fSockfd) ? true : false; } //IP/PORT*********************************************************************************************************** void JackNetWinSocket::SetPort(int port) { fPort = port; fSendAddr.sin_port = htons(port); fRecvAddr.sin_port = htons(port); } int JackNetWinSocket::GetPort() { return fPort; } //address*********************************************************************************************************** int JackNetWinSocket::SetAddress(const char* ip, int port) { fSendAddr.sin_addr.s_addr = inet_addr(ip); fSendAddr.sin_port = htons(port); return 0; } char* JackNetWinSocket::GetSendIP() { return inet_ntoa(fSendAddr.sin_addr); } char* JackNetWinSocket::GetRecvIP() { return inet_ntoa(fRecvAddr.sin_addr); } //utility************************************************************************************************************ int JackNetWinSocket::GetName(char* name) { return gethostname(name, 255); } int JackNetWinSocket::JoinMCastGroup(const char* ip) { struct ip_mreq multicast_req; multicast_req.imr_multiaddr.s_addr = inet_addr(ip); multicast_req.imr_interface.s_addr = htonl(INADDR_ANY); //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...) return SetOption(IPPROTO_IP, 12, &multicast_req, sizeof(multicast_req)); } //options************************************************************************************************************ int JackNetWinSocket::SetOption(int level, int optname, const void* optval, SOCKLEN optlen) { return setsockopt(fSockfd, level, optname, static_cast(optval), optlen); } int JackNetWinSocket::GetOption(int level, int optname, void* optval, SOCKLEN* optlen) { return getsockopt(fSockfd, level, optname, static_cast(optval), optlen); } //tiemout************************************************************************************************************ int JackNetWinSocket::SetTimeOut(int usec) { jack_log("JackNetWinSocket::SetTimeout %d usec", usec); int millisec = usec / 1000; return SetOption(SOL_SOCKET, SO_RCVTIMEO, &millisec, sizeof(millisec)); } //local loop********************************************************************************************************* int JackNetWinSocket::SetLocalLoop() { //char disable = 0; /* see http://msdn.microsoft.com/en-us/library/aa916098.aspx Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer. */ char disable = 1; return SetOption(IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof(disable)); } //network operations************************************************************************************************* int JackNetWinSocket::SendTo(const void* buffer, size_t nbytes, int flags) { return sendto(fSockfd, reinterpret_cast(buffer), nbytes, flags, reinterpret_cast(&fSendAddr), sizeof(SOCKADDR)); } int JackNetWinSocket::SendTo(const void* buffer, size_t nbytes, int flags, const char* ip) { fSendAddr.sin_addr.s_addr = inet_addr(ip); fSendAddr.sin_port = htons(fPort); return SendTo(buffer, nbytes, flags); } int JackNetWinSocket::Send(const void* buffer, size_t nbytes, int flags) { return send(fSockfd, reinterpret_cast(buffer), nbytes, flags); } int JackNetWinSocket::RecvFrom(void* buffer, size_t nbytes, int flags) { SOCKLEN addr_len = sizeof(SOCKADDR); return recvfrom(fSockfd, reinterpret_cast(buffer), nbytes, flags, reinterpret_cast(&fRecvAddr), &addr_len); } int JackNetWinSocket::Recv(void* buffer, size_t nbytes, int flags) { return recv(fSockfd, reinterpret_cast(buffer), nbytes, flags); } int JackNetWinSocket::CatchHost(void* buffer, size_t nbytes, int flags) { SOCKLEN addr_len = sizeof(SOCKADDR); return recvfrom(fSockfd, reinterpret_cast(buffer), nbytes, flags, reinterpret_cast(&fSendAddr), &addr_len); } net_error_t JackNetWinSocket::GetError() { switch (NET_ERROR_CODE) { case WSABASEERR: return NET_NO_ERROR; case WSAETIMEDOUT: return NET_NO_DATA; case WSAEWOULDBLOCK: return NET_NO_DATA; case WSAECONNREFUSED: return NET_CONN_ERROR; case WSAECONNRESET: return NET_CONN_ERROR; case WSAEACCES: return NET_CONN_ERROR; case WSAECONNABORTED: return NET_CONN_ERROR; case WSAEHOSTDOWN: return NET_CONN_ERROR; case WSAEHOSTUNREACH: return NET_CONN_ERROR; default: return NET_OP_ERROR; } } } 1.9.12~dfsg/windows/jack_midi_latency_test.cbp0000644000000000000000000001146313214314510020215 0ustar rootroot 1.9.12~dfsg/windows/jackd.cbp0000644000000000000000000001530413214314510014577 0ustar rootroot 1.9.12~dfsg/windows/JackShmMem_os.h0000644000000000000000000000343513214314510015670 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackShmMem_WIN32__ #define __JackShmMem_WIN32__ #include inline bool CHECK_MLOCK(void* ptr, size_t size) { if (!VirtualLock((ptr), (size))) { SIZE_T minWSS, maxWSS; HANDLE hProc = GetCurrentProcess(); if (GetProcessWorkingSetSize(hProc, &minWSS, &maxWSS)) { const size_t increase = size + (10 * 4096); maxWSS += increase; minWSS += increase; if (!SetProcessWorkingSetSize(hProc, minWSS, maxWSS)) { jack_error("SetProcessWorkingSetSize error = %d", GetLastError()); return false; } else if (!VirtualLock((ptr), (size))) { jack_error("VirtualLock error = %d", GetLastError()); return false; } else { return true; } } else { return false; } } else { return true; } } #define CHECK_MUNLOCK(ptr, size) (VirtualUnlock((ptr), (size)) != 0) #define CHECK_MLOCKALL()(false) #define CHECK_MUNLOCKALL()(false) #endif 1.9.12~dfsg/windows/JackRouter/0000755000000000000000000000000013244556535015125 5ustar rootroot1.9.12~dfsg/windows/JackRouter/JackRouter.h0000644000000000000000000001166213214314510017333 0ustar rootroot/* Copyright (C) 2006-2011 Grame Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _asiosmpl_ #define _asiosmpl_ #include "asiosys.h" // Globals static int kBlockFrames = 256; static int kNumInputs = 4; static int kNumOutputs = 4; #if WINDOWS #include "jack.h" #include "rpc.h" #include "rpcndr.h" #ifndef COM_NO_WINDOWS_H #include #include "ole2.h" #endif #include "combase.h" #include "iasiodrv.h" #define PATH_SEP "\\" #include #include class JackRouter : public IASIO, public CUnknown { public: JackRouter(LPUNKNOWN pUnk, HRESULT *phr); ~JackRouter(); DECLARE_IUNKNOWN //STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ // return GetOwner()->QueryInterface(riid,ppv); \ //}; \ //STDMETHODIMP_(ULONG) AddRef() { \ // return GetOwner()->AddRef(); \ //}; \ //STDMETHODIMP_(ULONG) Release() { \ // return GetOwner()->Release(); \ //}; // Factory method static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); // IUnknown virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); #else #include "asiodrvr.h" //--------------------------------------------------------------------------------------------- class JackRouter : public AsioDriver { public: JackRouter(); ~JackRouter(); #endif static int processCallback(jack_nframes_t nframes, void* arg); static void connectCallback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg); static void shutdownCallback(void* arg); ASIOBool init(void* sysRef); void getDriverName(char *name); // max 32 bytes incl. terminating zero long getDriverVersion(); void getErrorMessage(char *string); // max 128 bytes incl. ASIOError start(); ASIOError stop(); ASIOError getChannels(long *numInputChannels, long *numOutputChannels); ASIOError getLatencies(long *inputLatency, long *outputLatency); ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); ASIOError canSampleRate(ASIOSampleRate sampleRate); ASIOError getSampleRate(ASIOSampleRate *sampleRate); ASIOError setSampleRate(ASIOSampleRate sampleRate); ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); ASIOError setClockSource(long index); ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); ASIOError getChannelInfo(ASIOChannelInfo *info); ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks); ASIOError disposeBuffers(); ASIOError controlPanel(); ASIOError future(long selector, void *opt); ASIOError outputReady(); void bufferSwitch(); long getMilliSeconds() {return fMilliSeconds;} static std::list > fConnections; // Connections list private: void bufferSwitchX(); double fSamplePosition; ASIOCallbacks* fCallbacks; ASIOTime fAsioTime; ASIOTimeStamp fTheSystemTime; void** fInputBuffers; void** fOutputBuffers; long* fInMap; long* fOutMap; long fInputLatency; long fOutputLatency; long fActiveInputs; long fActiveOutputs; long fToggle; long fMilliSeconds; bool fRunning; bool fFirstActivate; bool fFloatSample; bool fAliasSystem; bool fTimeInfoMode, fTcRead; char fErrorMessage[128]; bool fAutoConnectIn; bool fAutoConnectOut; // Jack part jack_client_t* fClient; jack_port_t** fInputPorts; jack_port_t** fOutputPorts; long fBufferSize; ASIOSampleRate fSampleRate; void autoConnect(); void saveConnections(); void restoreConnections(); void processInputs(); void processOutputs(); }; #endif 1.9.12~dfsg/windows/JackRouter/JackRouter.cpp0000644000000000000000000007747413214314510017703 0ustar rootroot/* Copyright (C) 2006-2011 Grame Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifdef WIN32 #pragma warning (disable : 4786) #endif #include #include #include #include #include "JackRouter.h" #include "profport.h" /* 08/07/2007 SL : Use jack_client_open instead of jack_client_new (automatic client renaming). 09/08/2007 SL : Add JackRouter.ini parameter file. 09/20/2007 SL : Better error report in DllRegisterServer (for Vista). 09/27/2007 SL : Add AUDO_CONNECT property in JackRouter.ini file. 10/10/2007 SL : Use ASIOSTInt32LSB instead of ASIOSTInt16LSB. 12/04/2011 SL : Compilation on Windows 64. 12/04/2011 SL : Dynamic port allocation. Correct JACK port naming. */ //------------------------------------------------------------------------------------------ // extern void getNanoSeconds(ASIOTimeStamp *time); // local double AsioSamples2double (ASIOSamples* samples); static const double twoRaisedTo32 = 4294967296.; static const double twoRaisedTo32Reciprocal = 1. / twoRaisedTo32; //------------------------------------------------------------------------------------------ // on windows, we do the COM stuff. #if WINDOWS #include "windows.h" #include "mmsystem.h" #ifdef _WIN64 #define JACK_ROUTER "JackRouter.dll" #include #else #define JACK_ROUTER "JackRouter.dll" #include "./psapi.h" #endif using namespace std; //#define JACK_LOG 1 #ifdef JACK_LOG #include static std::ofstream* fStream; #endif // class id. // {838FE50A-C1AB-4b77-B9B6-0A40788B53F3} CLSID IID_ASIO_DRIVER = { 0x838fe50a, 0xc1ab, 0x4b77, { 0xb9, 0xb6, 0xa, 0x40, 0x78, 0x8b, 0x53, 0xf3 } }; CFactoryTemplate g_Templates[1] = { {L"ASIOJACK", &IID_ASIO_DRIVER, JackRouter::CreateInstance} }; int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); CUnknown* JackRouter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) { return (CUnknown*)new JackRouter(pUnk,phr); }; STDMETHODIMP JackRouter::NonDelegatingQueryInterface(REFIID riid, void ** ppv) { if (riid == IID_ASIO_DRIVER) { return GetInterface(this, ppv); } return CUnknown::NonDelegatingQueryInterface(riid, ppv); } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Register ASIO Driver // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ extern LONG RegisterAsioDriver(CLSID,char *,char *,char *,char *); extern LONG UnregisterAsioDriver(CLSID,char *,char *); // // Server registration, called on REGSVR32.EXE "the dllname.dll" // HRESULT _stdcall DllRegisterServer() { LONG rc; char errstr[128]; rc = RegisterAsioDriver (IID_ASIO_DRIVER, JACK_ROUTER,"JackRouter","JackRouter","Apartment"); if (rc) { memset(errstr,0,128); sprintf(errstr,"Register Server failed ! (%d)", rc); MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); return -1; } return S_OK; } // // Server unregistration // HRESULT _stdcall DllUnregisterServer() { LONG rc; char errstr[128]; rc = UnregisterAsioDriver (IID_ASIO_DRIVER,JACK_ROUTER,"JackRouter"); if (rc) { memset(errstr,0,128); sprintf(errstr,"Unregister Server failed ! (%d)",rc); MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); return -1; } return S_OK; } // Globals list > JackRouter::fConnections; //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ JackRouter::JackRouter (LPUNKNOWN pUnk, HRESULT *phr) : CUnknown("ASIOJACK", pUnk, phr) //------------------------------------------------------------------------------------------ #else // when not on windows, we derive from AsioDriver JackRouter::JackRouter() : AsioDriver() #endif { long i; fSamplePosition = 0; fRunning = false; fTimeInfoMode = false; fTcRead = false; fClient = NULL; fAutoConnectIn = true; fAutoConnectOut = true; fCallbacks = 0; fActiveInputs = fActiveOutputs = 0; fToggle = 0; fBufferSize = 512; fSampleRate = 44100; fFloatSample = true; // float by default fFirstActivate = true; #ifdef JACK_LOG fStream = new ofstream(name_log, ios_base::ate); *fStream << "======================" << std::endl; *fStream << "JackRouter::JackRouter" << std::endl; *fStream << "======================" << std::endl; #endif // Use "jackrouter.ini" parameters if available HMODULE handle = LoadLibrary(JACK_ROUTER); if (handle) { // Get JackRouter.dll path char dllName[512]; string confPath; DWORD res = GetModuleFileName(handle, dllName, 512); // Compute .ini file path string fullPath = dllName; int lastPos = fullPath.find_last_of(PATH_SEP); string dllFolder = fullPath.substr(0, lastPos); confPath = dllFolder + PATH_SEP + "JackRouter.ini"; // Get parameters kNumInputs = get_private_profile_int("IO", "input", 2, confPath.c_str()); kNumOutputs = get_private_profile_int("IO", "output", 2, confPath.c_str()); fAutoConnectIn = get_private_profile_int("AUTO_CONNECT", "input", 1, confPath.c_str()); fAutoConnectOut = get_private_profile_int("AUTO_CONNECT", "output", 1, confPath.c_str()); fFloatSample = get_private_profile_int("IO", "float-sample", 0, confPath.c_str()); fAliasSystem = get_private_profile_int("AUTO_CONNECT", "alias", 0, confPath.c_str()); FreeLibrary(handle); } else { #ifdef JACK_LOG *fStream << "JackRouter::JackRouter : loadLibrary error" << std::endl; #endif } if (!fFloatSample) { fInputBuffers = (void**)new long*[kNumInputs]; fOutputBuffers = (void**)new long*[kNumOutputs]; } else { fInputBuffers = (void**)new float*[kNumInputs]; fOutputBuffers = (void**)new float*[kNumOutputs]; } fInMap = new long[kNumInputs]; fOutMap = new long[kNumOutputs]; fInputPorts = new jack_port_t*[kNumInputs]; fOutputPorts = new jack_port_t*[kNumOutputs]; for (i = 0; i < kNumInputs; i++) { fInputBuffers[i] = 0; fInputPorts[i] = 0; fInMap[i] = 0; } for (i = 0; i < kNumOutputs; i++) { fOutputBuffers[i] = 0; fOutputPorts[i] = 0; fOutMap[i] = 0; } } //------------------------------------------------------------------------------------------ JackRouter::~JackRouter() { #ifdef JACK_LOG *fStream << "=======================" << std::endl; *fStream << "JackRouter::~JackRouter" << std::endl; *fStream << "=======================" << std::endl; #endif stop(); disposeBuffers(); jack_client_close(fClient); delete[] fInputBuffers; delete[] fOutputBuffers; delete[] fInputPorts; delete[] fOutputPorts; delete[] fInMap; delete[] fOutMap; #ifdef JACK_LOG delete fStream; #endif } //------------------------------------------------------------------------------------------ static bool GetEXEName(DWORD dwProcessID, char* name) { DWORD aProcesses [1024], cbNeeded, cProcesses; unsigned int i; // Enumerate all processes if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return false; // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); TCHAR szEXEName[MAX_PATH]; // Loop through all process to find the one that matches // the one we are looking for for (i = 0; i < cProcesses; i++) { if (aProcesses [i] == dwProcessID) { // Get a handle to the process HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID); // Get the process name if (NULL != hProcess) { HMODULE hMod; DWORD cbNeeded; if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) { //Get the name of the exe file GetModuleBaseName(hProcess, hMod, szEXEName, sizeof(szEXEName)/sizeof(TCHAR)); int len = strlen((char*)szEXEName) - 4; // remove ".exe" strncpy(name, (char*)szEXEName, len); name[len] = '\0'; return true; } } } } return false; } //------------------------------------------------------------------------------------------ static inline jack_default_audio_sample_t ClipFloat(jack_default_audio_sample_t sample) { return (sample < jack_default_audio_sample_t(-1.0)) ? jack_default_audio_sample_t(-1.0) : (sample > jack_default_audio_sample_t(1.0)) ? jack_default_audio_sample_t(1.0) : sample; } //------------------------------------------------------------------------------------------ void JackRouter::connectCallback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg) { JackRouter* driver = (JackRouter*)arg; } //------------------------------------------------------------------------------------------ void JackRouter::shutdownCallback(void* arg) { JackRouter* driver = (JackRouter*)arg; /* char errstr[128]; memset(errstr,0,128); sprintf(errstr,"JACK server has quitted"); MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); */ } //------------------------------------------------------------------------------------------ void JackRouter::processInputs() { int pos = (fToggle) ? 0 : fBufferSize; for (int i = 0; i < fActiveInputs; i++) { if (!fFloatSample) { jack_default_audio_sample_t* buffer = (jack_default_audio_sample_t*)jack_port_get_buffer(fInputPorts[i], fBufferSize); long* in = (long*)fInputBuffers[i] + pos; for (int j = 0; j < fBufferSize; j++) { in[j] = buffer[j] * jack_default_audio_sample_t(0x7fffffff); } } else { memcpy((float*)fInputBuffers[i] + pos, jack_port_get_buffer(fInputPorts[i], fBufferSize), fBufferSize * sizeof(jack_default_audio_sample_t)); } } } //------------------------------------------------------------------------------------------ void JackRouter::processOutputs() { int pos = (fToggle) ? 0 : fBufferSize; for (int i = 0; i < fActiveOutputs; i++) { if (!fFloatSample) { jack_default_audio_sample_t* buffer = (jack_default_audio_sample_t*)jack_port_get_buffer(fOutputPorts[i], fBufferSize); long* out = (long*)fOutputBuffers[i] + pos; jack_default_audio_sample_t gain = jack_default_audio_sample_t(1)/jack_default_audio_sample_t(0x7fffffff); for (int j = 0; j < fBufferSize; j++) { buffer[j] = out[j] * gain; } } else { memcpy(jack_port_get_buffer(fOutputPorts[i], fBufferSize), (float*)fOutputBuffers[i] + pos, fBufferSize * sizeof(jack_default_audio_sample_t)); } } } //------------------------------------------------------------------------------------------ int JackRouter::processCallback(jack_nframes_t nframes, void* arg) { JackRouter* driver = (JackRouter*)arg; driver->bufferSwitch(); return 0; } //------------------------------------------------------------------------------------------ void JackRouter::getDriverName(char *name) { strcpy(name, "JackRouter"); } //------------------------------------------------------------------------------------------ long JackRouter::getDriverVersion() { return 0x00000001L; } //------------------------------------------------------------------------------------------ void JackRouter::getErrorMessage(char *string) { strcpy (string, fErrorMessage); } //------------------------------------------------------------------------------------------ ASIOBool JackRouter::init(void* sysRef) { char name[MAX_PATH]; char name_log[MAX_PATH]; sysRef = sysRef; if (fClient) { #ifdef JACK_LOG *fStream << "JackRouter::init : JACK client still present..." << std::endl; #endif return true; } HANDLE win = (HANDLE)sysRef; int my_pid = _getpid(); if (!GetEXEName(my_pid, name)) { // If getting the .exe name fails, takes a generic one. _snprintf(name, sizeof(name) - 1, "JackRouter_%d", my_pid); } _snprintf(name_log, sizeof(name_log) - 1, "JackRouter_%s.log", name); fClient = jack_client_open(name, JackNoStartServer, NULL); if (fClient == NULL) { strcpy(fErrorMessage, "Open error: is JACK server running?"); printf("Open error: is JACK server running?\n"); return false; } fBufferSize = jack_get_buffer_size(fClient); fSampleRate = jack_get_sample_rate(fClient); jack_set_process_callback(fClient, processCallback, this); jack_on_shutdown(fClient, shutdownCallback, this); jack_set_port_connect_callback(fClient, connectCallback, this); fInputLatency = fBufferSize; // typically fOutputLatency = fBufferSize * 2; fMilliSeconds = (long)((double)(fBufferSize * 1000) / fSampleRate); // Typically fBufferSize * 2; try to get 1 by offering direct buffer // access, and using asioPostOutput for lower latency #ifdef JACK_LOG *fStream << "JackRouter::init" << std::endl; #endif return true; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::start() { if (fCallbacks) { fSamplePosition = 0; fTheSystemTime.lo = fTheSystemTime.hi = 0; fToggle = 0; #ifdef JACK_LOG *fStream << "JackRouter::start" << std::endl; #endif if (jack_activate(fClient) == 0) { if (fFirstActivate) { autoConnect(); fFirstActivate = false; } else { restoreConnections(); } fRunning = true; return ASE_OK; } else { return ASE_NotPresent; } } return ASE_NotPresent; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::stop() { #ifdef JACK_LOG *fStream << "JackRouter::stop" << std::endl; #endif fRunning = false; saveConnections(); if (jack_deactivate(fClient) == 0) { fFirstActivate = true; } return ASE_OK; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::getChannels(long *numInputChannels, long *numOutputChannels) { *numInputChannels = kNumInputs; *numOutputChannels = kNumOutputs; return ASE_OK; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::getLatencies(long *_inputLatency, long *_outputLatency) { *_inputLatency = fInputLatency; *_outputLatency = fOutputLatency; return ASE_OK; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) { *minSize = *maxSize = *preferredSize = fBufferSize; // Allows this size only *granularity = 0; return ASE_OK; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::canSampleRate(ASIOSampleRate sampleRate) { return (sampleRate == fSampleRate) ? ASE_OK : ASE_NoClock; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::getSampleRate(ASIOSampleRate *sampleRate) { *sampleRate = fSampleRate; return ASE_OK; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::setSampleRate(ASIOSampleRate sampleRate) { return (sampleRate == fSampleRate) ? ASE_OK : ASE_NoClock; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::getClockSources(ASIOClockSource *clocks, long *numSources) { // Internal if (clocks && numSources) { clocks->index = 0; clocks->associatedChannel = -1; clocks->associatedGroup = -1; clocks->isCurrentSource = ASIOTrue; strcpy(clocks->name, "Internal"); *numSources = 1; return ASE_OK; } else { return ASE_InvalidParameter; } } //------------------------------------------------------------------------------------------ ASIOError JackRouter::setClockSource(long index) { if (!index) { fAsioTime.timeInfo.flags |= kClockSourceChanged; return ASE_OK; } else { return ASE_NotPresent; } } //------------------------------------------------------------------------------------------ ASIOError JackRouter::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) { tStamp->lo = fTheSystemTime.lo; tStamp->hi = fTheSystemTime.hi; if (fSamplePosition >= twoRaisedTo32) { sPos->hi = (unsigned long)(fSamplePosition * twoRaisedTo32Reciprocal); sPos->lo = (unsigned long)(fSamplePosition - (sPos->hi * twoRaisedTo32)); } else { sPos->hi = 0; sPos->lo = (unsigned long)fSamplePosition; } return ASE_OK; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::getChannelInfo(ASIOChannelInfo *info) { if (info->channel < 0 || (info->isInput ? info->channel >= kNumInputs : info->channel >= kNumOutputs)) { return ASE_InvalidParameter; } if (!fFloatSample) { info->type = ASIOSTInt32LSB; } else { info->type = ASIOSTFloat32LSB; } #ifdef JACK_LOG *fStream << "==========================" << std::endl; *fStream << "JackRouter::getChannelInfo" << std::endl; *fStream << "==========================" << std::endl; #endif info->channelGroup = 0; info->isActive = ASIOFalse; long i; char buf[32]; const char** ports; char* aliases[2]; aliases[0] = (char*)malloc(jack_port_name_size()); aliases[1] = (char*)malloc(jack_port_name_size()); if (!aliases[0] || !aliases[1]) { return ASE_NoMemory; } if (info->isInput) { for (i = 0; i < fActiveInputs; i++) { if (fInMap[i] == info->channel) { info->isActive = ASIOTrue; break; } } // A alias on system is wanted if (fAliasSystem && fAutoConnectIn && (ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput))) { jack_port_t* port = jack_port_by_name(fClient, ports[info->channel]); if (port) { if (jack_port_get_aliases(port, aliases) == 2) { strncpy(info->name, aliases[1], 32); #ifdef JACK_LOG *fStream << "Input " << "fActiveInputs = " << i << " ASIO_channel = " << info->channel << std::endl; #endif goto end; } } } _snprintf(buf, sizeof(buf) - 1, "In%d", info->channel + 1); strcpy(info->name, buf); } else { for (i = 0; i < fActiveOutputs; i++) { if (fOutMap[i] == info->channel) { info->isActive = ASIOTrue; break; } } // A alias on system is wanted if (fAliasSystem && fAutoConnectOut && (ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput))) { jack_port_t* port = jack_port_by_name(fClient, ports[info->channel]); if (port) { if (jack_port_get_aliases(port, aliases) == 2) { strncpy(info->name, aliases[1], 32); #ifdef JACK_LOG *fStream << "Output " << "fActiveOutputs = " << i << " ASIO_channel = " << info->channel << std::endl; #endif goto end; } } } _snprintf(buf, sizeof(buf) - 1, "Out%d", info->channel + 1); strcpy(info->name, buf); } end: free(aliases[0]); free(aliases[1]); return ASE_OK; } //------------------------------------------------------------------------------------------ ASIOError JackRouter::createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks) { ASIOBufferInfo *info = bufferInfos; long i; bool notEnoughMem = false; char buf[256]; fActiveInputs = 0; fActiveOutputs = 0; #ifdef JACK_LOG *fStream << "==========================" << std::endl; *fStream << "JackRouter::createBuffers" << std::endl; *fStream << "==========================" << std::endl; #endif for (i = 0; i < numChannels; i++, info++) { if (info->isInput) { if (info->channelNum < 0 || info->channelNum >= kNumInputs) { goto error; } fInMap[fActiveInputs] = info->channelNum; if (!fFloatSample) { fInputBuffers[fActiveInputs] = new long[fBufferSize * 2]; // double buffer } else { fInputBuffers[fActiveInputs] = new jack_default_audio_sample_t[fBufferSize * 2]; // double buffer } if (fInputBuffers[fActiveInputs]) { info->buffers[0] = fInputBuffers[fActiveInputs]; info->buffers[1] = (fFloatSample) ? (void*)((float*)fInputBuffers[fActiveInputs] + fBufferSize) : (void*)((long*)fInputBuffers[fActiveInputs] + fBufferSize); } else { info->buffers[0] = info->buffers[1] = 0; notEnoughMem = true; } #ifdef JACK_LOG *fStream << "Input " << "fActiveInputs = " << i << " ASIO_channel = " << info->channelNum << std::endl; #endif _snprintf(buf, sizeof(buf) - 1, "in%d", info->channelNum + 1); fInputPorts[fActiveInputs] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput,0); if (fInputPorts[fActiveInputs] == NULL) { goto error; } fActiveInputs++; if (fActiveInputs > kNumInputs) { error: disposeBuffers(); return ASE_InvalidParameter; } } else { if (info->channelNum < 0 || info->channelNum >= kNumOutputs) { goto error; } fOutMap[fActiveOutputs] = info->channelNum; if (!fFloatSample) { fOutputBuffers[fActiveOutputs] = new long[fBufferSize * 2]; // double buffer } else { fOutputBuffers[fActiveOutputs] = new jack_default_audio_sample_t[fBufferSize * 2]; // double buffer } if (fOutputBuffers[fActiveOutputs]) { info->buffers[0] = fOutputBuffers[fActiveOutputs]; info->buffers[1] = (fFloatSample) ? (void*)((float*)fOutputBuffers[fActiveOutputs] + fBufferSize) : (void*)((long*)fOutputBuffers[fActiveOutputs] + fBufferSize); } else { info->buffers[0] = info->buffers[1] = 0; notEnoughMem = true; } #ifdef JACK_LOG *fStream << "Input " << "fActiveOutputs = " << i << " ASIO_channel = " << info->channelNum << std::endl; #endif _snprintf(buf, sizeof(buf) - 1, "out%d", info->channelNum + 1); fOutputPorts[fActiveOutputs] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput,0); if (fOutputPorts[fActiveOutputs] == NULL) { goto error; } fActiveOutputs++; if (fActiveOutputs > kNumOutputs) { fActiveOutputs--; disposeBuffers(); return ASE_InvalidParameter; } } } if (notEnoughMem) { disposeBuffers(); return ASE_NoMemory; } this->fCallbacks = callbacks; if (callbacks->asioMessage (kAsioSupportsTimeInfo, 0, 0, 0)) { fTimeInfoMode = true; fAsioTime.timeInfo.speed = 1.; fAsioTime.timeInfo.systemTime.hi = fAsioTime.timeInfo.systemTime.lo = 0; fAsioTime.timeInfo.samplePosition.hi = fAsioTime.timeInfo.samplePosition.lo = 0; fAsioTime.timeInfo.sampleRate = fSampleRate; fAsioTime.timeInfo.flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid; fAsioTime.timeCode.speed = 1.; fAsioTime.timeCode.timeCodeSamples.lo = fAsioTime.timeCode.timeCodeSamples.hi = 0; fAsioTime.timeCode.flags = kTcValid | kTcRunning ; } else { fTimeInfoMode = false; } if (fRunning) { autoConnect(); } return ASE_OK; } //--------------------------------------------------------------------------------------------- ASIOError JackRouter::disposeBuffers() { long i; fCallbacks = 0; stop(); for (i = 0; i < fActiveInputs; i++) { delete[] fInputBuffers[i]; jack_port_unregister(fClient, fInputPorts[i]); } fActiveInputs = 0; for (i = 0; i < fActiveOutputs; i++) { delete[] fOutputBuffers[i]; jack_port_unregister(fClient, fOutputPorts[i]); } fActiveOutputs = 0; return ASE_OK; } //--------------------------------------------------------------------------------------------- ASIOError JackRouter::controlPanel() { return ASE_NotPresent; } //--------------------------------------------------------------------------------------------- ASIOError JackRouter::future(long selector, void* opt) // !!! check properties { ASIOTransportParameters* tp = (ASIOTransportParameters*)opt; switch (selector) { case kAsioEnableTimeCodeRead: fTcRead = true; return ASE_SUCCESS; case kAsioDisableTimeCodeRead: fTcRead = false; return ASE_SUCCESS; case kAsioSetInputMonitor: return ASE_SUCCESS; // for testing!!! case kAsioCanInputMonitor: return ASE_SUCCESS; // for testing!!! case kAsioCanTimeInfo: return ASE_SUCCESS; case kAsioCanTimeCode: return ASE_SUCCESS; } return ASE_NotPresent; } //-------------------------------------------------------------------------------------------------------- // private methods //-------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- void JackRouter::bufferSwitch() { if (fRunning && fCallbacks) { getNanoSeconds(&fTheSystemTime); // latch system time processInputs(); processOutputs(); fSamplePosition += fBufferSize; if (fTimeInfoMode) { bufferSwitchX(); } else { fCallbacks->bufferSwitch(fToggle, ASIOFalse); } fToggle = fToggle ? 0 : 1; } } //--------------------------------------------------------------------------------------------- // asio2 buffer switch void JackRouter::bufferSwitchX() { getSamplePosition (&fAsioTime.timeInfo.samplePosition, &fAsioTime.timeInfo.systemTime); long offset = fToggle ? fBufferSize : 0; if (fTcRead) { // Create a fake time code, which is 10 minutes ahead of the card's sample position // Please note that for simplicity here time code will wrap after 32 bit are reached fAsioTime.timeCode.timeCodeSamples.lo = fAsioTime.timeInfo.samplePosition.lo + 600.0 * fSampleRate; fAsioTime.timeCode.timeCodeSamples.hi = 0; } fCallbacks->bufferSwitchTimeInfo(&fAsioTime, fToggle, ASIOFalse); fAsioTime.timeInfo.flags &= ~(kSampleRateChanged | kClockSourceChanged); } //--------------------------------------------------------------------------------------------- ASIOError JackRouter::outputReady() { return ASE_NotPresent; } //--------------------------------------------------------------------------------------------- double AsioSamples2double(ASIOSamples* samples) { double a = (double)(samples->lo); if (samples->hi) { a += (double)(samples->hi) * twoRaisedTo32; } return a; } //--------------------------------------------------------------------------------------------- void getNanoSeconds(ASIOTimeStamp* ts) { double nanoSeconds = (double)((unsigned long)timeGetTime ()) * 1000000.; ts->hi = (unsigned long)(nanoSeconds / twoRaisedTo32); ts->lo = (unsigned long)(nanoSeconds - (ts->hi * twoRaisedTo32)); } //------------------------------------------------------------------------ void JackRouter::saveConnections() { const char** connections; int i; for (i = 0; i < fActiveInputs; ++i) { if (fInputPorts[i] && (connections = jack_port_get_connections(fInputPorts[i])) != 0) { for (int j = 0; connections[j]; j++) { fConnections.push_back(make_pair(connections[j], jack_port_name(fInputPorts[i]))); } jack_free(connections); } } for (i = 0; i < fActiveOutputs; ++i) { if (fOutputPorts[i] && (connections = jack_port_get_connections(fOutputPorts[i])) != 0) { for (int j = 0; connections[j]; j++) { fConnections.push_back(make_pair(jack_port_name(fOutputPorts[i]), connections[j])); } jack_free(connections); } } } //------------------------------------------------------------------------ void JackRouter::restoreConnections() { list >::const_iterator it; for (it = fConnections.begin(); it != fConnections.end(); it++) { pair connection = *it; jack_connect(fClient, connection.first.c_str(), connection.second.c_str()); } fConnections.clear(); } //------------------------------------------------------------------------------------------ void JackRouter::autoConnect() { const char** ports; #ifdef JACK_LOG *fStream << "=======================" << std::endl; *fStream << "JackRouter::autoConnect" << std::endl; *fStream << "=======================" << std::endl; #endif if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput)) == NULL) { #ifdef JACK_LOG *fStream << "JackRouter::autoConnect : cannot find any physical capture ports" << std::endl; #endif } else { if (fAutoConnectIn) { for (int i = 0; i < fActiveInputs; i++) { long ASIO_channel = fInMap[i]; if (!ports[ASIO_channel]) { printf("source port is null ASIO_channel = %ld\n", ASIO_channel); break; } else if (jack_connect(fClient, ports[ASIO_channel], jack_port_name(fInputPorts[i])) != 0) { printf("Cannot connect input ports\n"); } else { #ifdef JACK_LOG *fStream << "Input " << "fActiveInputs = " << i << " ASIO_channel = " << ASIO_channel << std::endl; #endif } } } jack_free(ports); } if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput)) == NULL) { #ifdef JACK_LOG *fStream << "JackRouter::autoConnect : cannot find any physical playback ports" << std::endl; #endif } else { if (fAutoConnectOut) { for (int i = 0; i < fActiveOutputs; i++) { long ASIO_channel = fOutMap[i]; if (!ports[ASIO_channel]) { printf("destination port is null ASIO_channel = %ld\n", ASIO_channel); break; } else if (jack_connect(fClient, jack_port_name(fOutputPorts[i]), ports[ASIO_channel]) != 0) { printf("Cannot connect output ports\n"); } else { #ifdef JACK_LOG *fStream << "Output " << "fActiveOutputs = " << i << " ASIO_channel = " << ASIO_channel << std::endl; #endif } } } jack_free(ports); } } 1.9.12~dfsg/windows/JackRouter/profport.h0000644000000000000000000000252113214314510017127 0ustar rootroot /****************************************************************************** PORTABLE ROUTINES FOR WRITING PRIVATE PROFILE STRINGS -- by Joseph J. Graf Header file containing prototypes and compile-time configuration. [09/05/02] D. Fober - Windows definitions added ******************************************************************************/ #ifndef __profport__ #define __profport__ #define MAX_LINE_LENGTH 1024 #ifdef __cplusplus extern "C" { #endif #ifdef WIN32 #include "Windows.h" #define get_private_profile_int GetPrivateProfileInt #define get_private_profile_string GetPrivateProfileString #define write_private_profile_string WritePrivateProfileString #define write_private_profile_int WritePrivateProfileInt #else int get_private_profile_int (char * section, char * entry, int def, char * file_name); int get_private_profile_string (char * section, char * entry, char * def, char * buffer, int buffer_len, char * file_name); int write_private_profile_string (char * section, char * entry, char * buffer, char * file_name); int write_private_profile_int (char * section, char * entry, int val, char * file_name); #endif float get_private_profile_float (char * section, char * entry, float def, char * file_name); #ifdef __cplusplus } #endif #endif //__profport__ 1.9.12~dfsg/windows/JackRouter/psapi.h0000644000000000000000000000576713214314510016407 0ustar rootroot/* psapi.h - Include file for PSAPI.DLL APIs Written by Mumit Khan This file is part of a free library for the Win32 API. NOTE: This strictly does not belong in the Win32 API since it's really part of Platform SDK. However,GDB needs it and we might as well provide it here. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef _PSAPI_H #define _PSAPI_H #if __GNUC__ >=3 #pragma GCC system_header #endif #ifdef __cplusplus extern "C" { #endif #ifndef RC_INVOKED typedef struct _MODULEINFO { LPVOID lpBaseOfDll; DWORD SizeOfImage; LPVOID EntryPoint; } MODULEINFO,*LPMODULEINFO; typedef struct _PSAPI_WS_WATCH_INFORMATION { LPVOID FaultingPc; LPVOID FaultingVa; } PSAPI_WS_WATCH_INFORMATION,*PPSAPI_WS_WATCH_INFORMATION; typedef struct _PROCESS_MEMORY_COUNTERS { DWORD cb; DWORD PageFaultCount; DWORD PeakWorkingSetSize; DWORD WorkingSetSize; DWORD QuotaPeakPagedPoolUsage; DWORD QuotaPagedPoolUsage; DWORD QuotaPeakNonPagedPoolUsage; DWORD QuotaNonPagedPoolUsage; DWORD PagefileUsage; DWORD PeakPagefileUsage; } PROCESS_MEMORY_COUNTERS,*PPROCESS_MEMORY_COUNTERS; /* Grouped by application,not in alphabetical order. */ BOOL WINAPI EnumProcesses(DWORD *,DWORD,DWORD *); BOOL WINAPI EnumProcessModules(HANDLE,HMODULE *,DWORD,LPDWORD); DWORD WINAPI GetModuleBaseNameA(HANDLE,HMODULE,LPSTR,DWORD); DWORD WINAPI GetModuleBaseNameW(HANDLE,HMODULE,LPWSTR,DWORD); DWORD WINAPI GetModuleFileNameExA(HANDLE,HMODULE,LPSTR,DWORD); DWORD WINAPI GetModuleFileNameExW(HANDLE,HMODULE,LPWSTR,DWORD); BOOL WINAPI GetModuleInformation(HANDLE,HMODULE,LPMODULEINFO,DWORD); BOOL WINAPI EmptyWorkingSet(HANDLE); BOOL WINAPI QueryWorkingSet(HANDLE,PVOID,DWORD); BOOL WINAPI InitializeProcessForWsWatch(HANDLE); BOOL WINAPI GetWsChanges(HANDLE,PPSAPI_WS_WATCH_INFORMATION,DWORD); DWORD WINAPI GetMappedFileNameW(HANDLE,LPVOID,LPWSTR,DWORD); DWORD WINAPI GetMappedFileNameA(HANDLE,LPVOID,LPSTR,DWORD); BOOL WINAPI EnumDeviceDrivers(LPVOID *,DWORD,LPDWORD); DWORD WINAPI GetDeviceDriverBaseNameA(LPVOID,LPSTR,DWORD); DWORD WINAPI GetDeviceDriverBaseNameW(LPVOID,LPWSTR,DWORD); DWORD WINAPI GetDeviceDriverFileNameA(LPVOID,LPSTR,DWORD); DWORD WINAPI GetDeviceDriverFileNameW(LPVOID,LPWSTR,DWORD); BOOL WINAPI GetProcessMemoryInfo(HANDLE,PPROCESS_MEMORY_COUNTERS,DWORD); #endif /* not RC_INVOKED */ #ifdef UNICODE #define GetModuleBaseName GetModuleBaseNameW #define GetModuleFileNameEx GetModuleFileNameExW #define GetMappedFilenameEx GetMappedFilenameExW #define GetDeviceDriverBaseName GetDeviceDriverBaseNameW #define GetDeviceDriverFileName GetDeviceDriverFileNameW #else #define GetModuleBaseName GetModuleBaseNameA #define GetModuleFileNameEx GetModuleFileNameExA #define GetMappedFilenameEx GetMappedFilenameExA #define GetDeviceDriverBaseName GetDeviceDriverBaseNameA #define GetDeviceDriverFileName GetDeviceDriverFileNameA #endif #ifdef __cplusplus } #endif #endif /* _PSAPI_H */ 1.9.12~dfsg/windows/JackRouter/JackRouter.def0000644000000000000000000000026413214314510017636 0ustar rootrootLIBRARY JackRouter DESCRIPTION 'ASIO Jack Driver' PROTMODE EXPORTS DllMain DllGetClassObject DllCanUnloadNow DllRegisterServer DllUnregisterServer 1.9.12~dfsg/windows/JackRouter/JackRouter.vcxproj.user0000644000000000000000000000033613214314510021550 0ustar rootroot false 1.9.12~dfsg/windows/JackRouter/README0000644000000000000000000000071413214314510015765 0ustar rootrootThis folder contains the sources for ASIO/JACK bridge ASIO driver called "JackRouter". The included project is a Microsoft VC++ 6 one. It requires some files (combase.cpp, dllentry.cpp, register.cpp) that are part on the ASIO driver SDK. The produced "JackRouter.dll" file has to be registered in the system using the "regsvr32" tool. 64 bits compilation ==================== A Visual Studio 10 project has been added to compile 64 and 32 bits targets.1.9.12~dfsg/windows/JackRouter/resource.h0000644000000000000000000000063313214314510017105 0ustar rootroot//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by resource.rc // // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif 1.9.12~dfsg/windows/JackRouter/JackRouter.dsw0000644000000000000000000000104113214314510017667 0ustar rootrootMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "JackRouter"=".\JackRouter.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### 1.9.12~dfsg/windows/JackRouter/JackRouter.vcxproj0000644000000000000000000003443213214314510020577 0ustar rootroot Debug Win32 Debug x64 Release Win32 Release x64 DynamicLibrary false DynamicLibrary false DynamicLibrary false DynamicLibrary false .\Debug\ .\Debug\ true .\Debug\ .\Debug\ true .\Release\ .\Release\ false .\Release64\ .\Release64\ false MultiThreadedDebugDLL Default false Disabled true Level3 true ..\..\..\..\..\ASIOSDK2\common;..\..\common;..\..\common\jack;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) .\Debug\ true .\Debug\JackRouter.pch .\Debug\ .\Debug\ EnableFastChecks true _DEBUG;%(PreprocessorDefinitions) .\Debug\JackRouter.tlb true Win32 0x0409 _DEBUG;%(PreprocessorDefinitions) true .\Debug\JackRouter.bsc true true true Windows Debug/JackRouter_debug.dll .\Debug\JackRouter_debug.lib odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies) .\JackRouter.def MultiThreadedDebugDLL Default false Disabled true Level3 ..\..\..\..\..\ASIOSDK2\common;..\..\common;..\..\common\jack;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) .\Debug\ true .\Debug\JackRouter.pch .\Debug\ .\Debug\ EnableFastChecks true _DEBUG;%(PreprocessorDefinitions) .\Debug\JackRouter.tlb true 0x0409 _DEBUG;%(PreprocessorDefinitions) true .\Debug\JackRouter.bsc true true true Windows Debug/JackRouter_debug.dll .\Debug\JackRouter_debug.lib odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies) .\JackRouter.def MultiThreadedDLL OnlyExplicitInline true true MaxSpeed true Level3 ..\..\..\..\..\ASIOSDK2\common;..\..\common;..\..\common\jack;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) .\Release\ true .\Release\JackRouter.pch .\Release\ .\Release\ true NDEBUG;%(PreprocessorDefinitions) .\Release\JackRouter.tlb true Win32 0x0409 NDEBUG;%(PreprocessorDefinitions) true .\Release\JackRouter.bsc true true Windows .\Release\JackRouter.dll .\Release\JackRouter.lib odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies) .\JackRouter.def MultiThreadedDLL OnlyExplicitInline true true MaxSpeed true Level3 ..\..\..\..\..\ASIOSDK2\common;..\..\common;..\..\common\jack;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;PSAPI_VERSION=2;%(PreprocessorDefinitions) .\Release\ true .\Release\JackRouter.pch .\Release\ .\Release\ true NDEBUG;%(PreprocessorDefinitions) .\Release\JackRouter.tlb true 0x0409 NDEBUG;%(PreprocessorDefinitions) true .\Release\JackRouter64.bsc true true Windows .\Release64\JackRouter.dll .\Release\JackRouter64.lib odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies) .\JackRouter.def 1.9.12~dfsg/windows/JackRouter/JackRouter.vcxproj.filters0000644000000000000000000000467213214314510022251 0ustar rootroot {72f2b2b0-dbea-4574-94fa-0c1ea89a3c8e} cpp;c;cxx;rc;def;r;odl;idl;hpj;bat {9590ca0b-94c8-4c22-88b2-66724eb0ea21} h;hpp;hxx;hm;inl {9742e150-2741-4bf4-9b81-bea4aab464af} ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files 1.9.12~dfsg/windows/JackRouter/JackRouter.dsp0000644000000000000000000001230713214314510017667 0ustar rootroot# Microsoft Developer Studio Project File - Name="JackRouter" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=JackRouter - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "JackRouter.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "JackRouter.mak" CFG="JackRouter - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "JackRouter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "JackRouter - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "JackRouter - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\ASIOSDK2\common" /I "..\..\common" /I "..\..\common\jack" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /machine:I386 !ELSEIF "$(CFG)" == "JackRouter - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c # ADD CPP /nologo /G5 /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\ASIOSDK2\common" /I "..\..\common" /I "..\..\common\jack" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Debug/JackRouter_debug.dll" /pdbtype:sept !ENDIF # Begin Target # Name "JackRouter - Win32 Release" # Name "JackRouter - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\..\..\..\..\ASIOSDK2\common\combase.cpp # End Source File # Begin Source File SOURCE=..\..\..\..\..\ASIOSDK2\common\dllentry.cpp # End Source File # Begin Source File SOURCE=.\JackRouter.cpp # End Source File # Begin Source File SOURCE=.\JackRouter.def # End Source File # Begin Source File SOURCE=.\profport.cpp # End Source File # Begin Source File SOURCE=..\..\..\..\..\ASIOSDK2\common\register.cpp # End Source File # Begin Source File SOURCE=.\resource.rc # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\..\..\common\asio.h # End Source File # Begin Source File SOURCE=..\..\Common\Asiodrvr.h # End Source File # Begin Source File SOURCE=..\asiosmpl.h # End Source File # Begin Source File SOURCE=..\..\..\common\asiosys.h # End Source File # Begin Source File SOURCE=..\..\..\common\combase.h # End Source File # Begin Source File SOURCE=..\..\..\common\iasiodrv.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\Psapi.Lib # End Source File # Begin Source File SOURCE=..\Release\bin\libjack.lib # End Source File # End Target # End Project 1.9.12~dfsg/windows/JackRouter/profport.cpp0000644000000000000000000002335113214314510017466 0ustar rootroot/* History : 01-28-02 : Change the location of temporary files created in write_private_profile_string now done in TmpDirectory. 01-29-02 : Correct bug when the '=' character is not present. 06-18-02 : Return default value if file does not exist, new write_private_profile_int function. */ /***** Routines to read profile strings -- by Joseph J. Graf ******/ /***** corrections and improvements -- by D. Fober - Grame ******/ /* corrections: buffer sizes control improvements: behavior more similar to windows */ #include #include #include #include #include #include #include "profport.h" /* function prototypes in here */ #ifndef _WIN32 static int read_line (FILE *fp, char *bp, int size); static int read_section(FILE *fp, char *section); static int read_entry (FILE *fp, char *entry, char *buff, int size); static char * read_value (char *buff); static int read_int_value (char *buff, int def); static char * read_file (char *file); static char * str_search (char * buff, char * str, int stopCond); /***************************************************************** * Function: read_line() * Arguments: fp - a pointer to the file to be read from * bp - a pointer to the copy buffer * size - size of the copy buffer * Returns: the line length if successful -1 otherwise ******************************************************************/ static int read_line(FILE *fp, char *bp, int size) { char c = '\0'; int i = 0, limit = size-2; /* Read one line from the source file */ while (((c = getc(fp)) != '\n') && (i < limit)) { if (c == EOF) { if (!i) return -1; else break; } bp[i++] = c; } bp[i] = '\0'; return i; } static int read_section (FILE *fp, char *section) { char buff[MAX_LINE_LENGTH]; char t_section[MAX_LINE_LENGTH]; int n, slen; sprintf(t_section,"[%s]", section); /* Format the section name */ slen = strlen (t_section); /* Move through file 1 line at a time until a section is matched or EOF */ do { n = read_line(fp, buff, MAX_LINE_LENGTH); if (n == -1) return 0; } while (strncmp (buff,t_section, slen)); return 1; } static int read_entry (FILE *fp, char *entry, char *buff, int size) { int n, elen = strlen (entry); do { n = read_line(fp, buff, size); if (n == -1) return 0; else if (*buff == '[') return 0; } while (strncmp (buff, entry, elen)); return 1; } #define isBlank(c) ((c == ' ') || (c == '\t')) static char * read_value (char *buff) { char * eq = strrchr (buff,'='); /* Parse out the equal sign */ if (eq) { eq++; while (*eq && isBlank(*eq)) eq++; // return *eq ? eq : 0; return eq; } return eq; } #define isSignedDigit(c) (isdigit(c) || (c == '+') || (c == '-')) static int read_int_value (char *buff, int def) { char * val = read_value (buff); char value[20]; int i; if (!*val) return def; for (i = 0; isSignedDigit(*val) && (i <= 10); i++ ) value[i] = *val++; value[i] = '\0'; return value[0] ? atoi(value) : def; } static char * read_file (char *file) { FILE *fd = fopen (file,"r"); int size; char * buff = 0; if (!fd) return 0; if (fseek (fd, 0, SEEK_END) == -1) goto err; size = ftell (fd); if (size < 0) goto err; if (fseek (fd, 0, SEEK_SET) == -1) goto err; buff = (char *) malloc (size+1); if (buff) { *buff = 0; fread (buff, 1, size, fd); buff[size] = 0; } err: fclose (fd); return buff; } static char * str_search (char * buff, char * str, int stopCond) { char *ptr = buff; int len = strlen (str); while (*ptr && strncmp (ptr, str, len)) { while (*ptr && (*ptr++ != '\n')) ; if (*ptr == stopCond) return 0; } return *ptr ? ptr : 0; } /************************************************************************** * Function: get_private_profile_int() * Arguments: section - the name of the section to search for * entry - the name of the entry to find the value of * def - the default value in the event of a failed read * file_name - the name of the .ini file to read from * Returns: the value located at entry ***************************************************************************/ int get_private_profile_int(char *section, char *entry, int def, char *file_name) { FILE *fp = fopen(file_name,"r"); char buff[MAX_LINE_LENGTH]; if( !fp ) return def; /* Return default value if file does not exist */ if (!read_section (fp, section)) goto err; if (!read_entry (fp, entry, buff, MAX_LINE_LENGTH)) goto err; def = read_int_value (buff, def); err: fclose (fp); return def; } /************************************************************************** * Function: get_private_profile_string() * Arguments: section - the name of the section to search for * entry - the name of the entry to find the value of * def - default string in the event of a failed read * buffer - a pointer to the buffer to copy into * buffer_len - the max number of characters to copy * file_name - the name of the .ini file to read from * Returns: the number of characters copied into the supplied buffer ***************************************************************************/ int get_private_profile_string(char *section, char *entry, char *def, char *buffer, int buffer_len, char *file_name) { FILE *fp = fopen (file_name,"r"); char buff[MAX_LINE_LENGTH]; char *val; if( !fp ) goto err; /* Return default value if file does not exist */ if (!read_section (fp, section)) goto err; if (!read_entry (fp, entry, buff, MAX_LINE_LENGTH)) goto err; val = read_value (buff); if(val) def = val; err: if (fp) fclose (fp); if (def) { strncpy (buffer, def, buffer_len - 1); buffer[buffer_len] = '\0'; } else buffer[buffer_len] = '\0'; return strlen (buffer); } /*************************************************************************** * Function: write_private_profile_string() * Arguments: section - the name of the section to search for * entry - the name of the entry to find the value of * buffer - pointer to the buffer that holds the string * file_name - the name of the .ini file to read from * Returns: TRUE if successful, otherwise FALSE ***************************************************************************/ int write_private_profile_string(char *section, char *entry, char *buffer, char *file_name) { char * content = read_file(file_name); FILE * fd = fopen(file_name,"w"); char t_section[MAX_LINE_LENGTH], *ptr; int ret = 0; if (!fd) goto end; if (!content) { fprintf (fd, "[%s]\n%s = %s\n", section, entry, buffer); ret = 1; goto end; } sprintf(t_section,"[%s]",section); /* Format the section name */ ptr = str_search (content, t_section, 0); /* look for the section start */ if (!ptr) { /* no such section: add the new section at end of file */ fprintf (fd, "%s\n[%s]\n%s = %s\n", content, section, entry, buffer); } else { char * eptr; eptr = str_search (ptr, entry, '['); if (!eptr) { /* no such entry: looks for next section */ eptr = str_search (++ptr, "[", 0); if (!eptr) { /* section is the last one */ fprintf (fd, "%s\n%s = %s\n", content, entry, buffer); } else { while (*ptr && (*ptr != '\n')) ptr++; *ptr = 0; fprintf (fd, "%s\n%s = %s", content, entry, buffer); *ptr = '\n'; fprintf (fd, "%s", ptr); } } else { *eptr++ = 0; fprintf (fd, "%s%s = %s", content, entry, buffer); while (*eptr && (*eptr != '\n')) eptr++; if (eptr) fprintf (fd, "%s", eptr); } } ret = 1; end: if (content) free(content); if (fd) fclose(fd); return 0; } /*************************************************************************** * Function: write_private_profile_int() * Arguments: section - the name of the section to search for * entry - the name of the entry to find the value of * buffer - the value to be written * file_name - the name of the .ini file to read from * Returns: TRUE if successful, otherwise FALSE ***************************************************************************/ int write_private_profile_int(char *section, char *entry, int val, char *file_name) { char buffer [64]; sprintf(buffer, "%d", val); return write_private_profile_string (section,entry, buffer, file_name); } #endif // #ifndef WIN32 /************************************************************************** * Function: get_private_profile_float() * Arguments: section - the name of the section to search for * entry - the name of the entry to find the value of * def - the default value in the event of a failed read * file_name - the name of the .ini file to read from * Returns: the value located at entry * Warning: The float value to be read must not contain more than 100 digits. * Author: CD, 15/11/2006. ***************************************************************************/ #define maxFloatLen 100 float get_private_profile_float (char * section, char * entry, float def, char * file_name) { float result = def; char buffer[ maxFloatLen ], *endptr; if ( get_private_profile_string(section, entry, "", buffer, maxFloatLen, file_name) > 0 ) { result = (float)strtod(buffer, &endptr); if ((result==0) && (endptr==buffer)) result = def; } return result; } 1.9.12~dfsg/windows/jack_unload.cbp0000644000000000000000000001123013214314510015767 0ustar rootroot 1.9.12~dfsg/windows/JackWinProcessSync.h0000644000000000000000000000411613214314510016727 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinProcessSync__ #define __JackWinProcessSync__ #include "JackWinMutex.h" namespace Jack { /*! \brief A synchronization primitive built using a condition variable. */ class JackWinProcessSync : public JackWinMutex { private: HANDLE fEvent; public: JackWinProcessSync(const char* name = NULL):JackWinMutex(name) { if (name) { char buffer[MAX_PATH]; snprintf(buffer, sizeof(buffer), "%s_%s", "JackWinProcessSync", name); fEvent = CreateEvent(NULL, TRUE, FALSE, buffer); // Needs ResetEvent //fEvent = CreateEvent(NULL, FALSE, FALSE, buffer); // Auto-reset event } else { fEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // Needs ResetEvent //fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto-reset event } ThrowIf((fEvent == 0), JackException("JackWinProcessSync: could not init the event")); } virtual ~JackWinProcessSync() { CloseHandle(fEvent); } bool TimedWait(long usec); bool LockedTimedWait(long usec); void Wait(); void LockedWait(); void Signal(); void LockedSignal(); void SignalAll(); void LockedSignalAll(); }; } // end of namespace #endif 1.9.12~dfsg/windows/JackWinThread.h0000644000000000000000000000566013214314510015670 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinThread__ #define __JackWinThread__ #include "JackThread.h" #include "JackMMCSS.h" #include "JackCompilerDeps.h" #include "JackSystemDeps.h" #include namespace Jack { typedef DWORD (WINAPI *ThreadCallback)(void *arg); /*! \brief Windows threads. */ class SERVER_EXPORT JackWinThread : public JackMMCSS, public detail::JackThreadInterface { private: HANDLE fThread; HANDLE fEvent; static DWORD WINAPI ThreadHandler(void* arg); public: JackWinThread(JackRunnableInterface* runnable); ~JackWinThread(); int Start(); int StartSync(); int Kill(); int Stop(); void Terminate(); int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself jack_native_thread_t GetThreadID(); bool IsThread(); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) { return JackWinThread::AcquireRealTimeImp(thread, priority); } static int DropRealTimeImp(jack_native_thread_t thread); static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) { return JackWinThread::StartImp(thread, priority, realtime, (ThreadCallback) start_routine, arg); } static int StartImp(jack_native_thread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg); static int StopImp(jack_native_thread_t thread); static int KillImp(jack_native_thread_t thread); }; SERVER_EXPORT void ThreadExit(); } // end of namespace #endif 1.9.12~dfsg/windows/JackPlatformPlug_os.h0000644000000000000000000000535713214314510017123 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPlatformPlug_WIN32__ #define __JackPlatformPlug_WIN32__ #define jack_server_dir "server" #define jack_client_dir "client" #define JACK_DEFAULT_DRIVER "portaudio" #define JACK_LOCATION "C:/Program Files/Jack" #ifndef ADDON_DIR #define ADDON_DIR "jack" #endif namespace Jack { struct JackRequest; struct JackResult; class JackWinMutex; class JackWinThread; class JackWinSemaphore; class JackWinProcessSync; class JackWinNamedPipeServerChannel; class JackWinNamedPipeClientChannel; class JackWinNamedPipeServerNotifyChannel; class JackWinNamedPipeNotifyChannel; class JackWinNamedPipe; class JackNetWinSocket; } /* __JackPlatformMutex__ */ #include "JackWinMutex.h" namespace Jack {typedef JackWinMutex JackMutex; } /* __JackPlatformThread__ */ #include "JackWinThread.h" namespace Jack { typedef JackWinThread JackThread; } /* __JackPlatformSynchro__ client activation */ #include "JackWinSemaphore.h" namespace Jack { typedef JackWinSemaphore JackSynchro; } /* __JackPlatformChannelTransaction__ */ #include "JackWinNamedPipe.h" namespace Jack { typedef JackWinNamedPipe JackChannelTransaction; } /* __JackPlatformProcessSync__ */ #include "JackWinProcessSync.h" namespace Jack { typedef JackWinProcessSync JackProcessSync; } /* __JackPlatformServerChannel__ */ #include "JackWinNamedPipeServerChannel.h" namespace Jack { typedef JackWinNamedPipeServerChannel JackServerChannel; } /* __JackPlatformClientChannel__ */ #include "JackWinNamedPipeClientChannel.h" namespace Jack { typedef JackWinNamedPipeClientChannel JackClientChannel; } /* __JackPlatformServerNotifyChannel__ */ #include "JackWinNamedPipeServerNotifyChannel.h" namespace Jack { typedef JackWinNamedPipeServerNotifyChannel JackServerNotifyChannel; } /* __JackPlatformNotifyChannel__ */ #include "JackWinNamedPipeNotifyChannel.h" namespace Jack { typedef JackWinNamedPipeNotifyChannel JackNotifyChannel; } /* __JackPlatformNetSocket__ */ #include "JackNetWinSocket.h" namespace Jack { typedef JackNetWinSocket JackNetSocket; } #endif 1.9.12~dfsg/windows/JackWinEvent.h0000644000000000000000000000335713214314510015543 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinEvent__ #define __JackWinEvent__ #include "JackSynchro.h" #include namespace Jack { // http://bob.developpez.com/tutapiwin/article_56.php /*! \brief Inter process synchronization using system wide events. */ class JackWinEvent : public JackSynchro { private: HANDLE fEvent; protected: void BuildName(const char* name, const char* server_name, char* res, int size); public: JackWinEvent(): JackSynchro(), fEvent(NULL) {} virtual ~JackWinEvent() {} bool Signal(); bool SignalAll(); bool Wait(); bool TimedWait(long usec); bool Allocate(const char* name, const char* server_name, int value); bool Connect(const char* name, const char* server_name); bool ConnectInput(const char* name, const char* server_name); bool ConnectOutput(const char* name, const char* server_name); bool Disconnect(); void Destroy(); }; } // end of namespace #endif 1.9.12~dfsg/windows/JackWinProcessSync.cpp0000644000000000000000000002017413214314510017264 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackWinProcessSync.h" #include "JackError.h" namespace Jack { void JackWinProcessSync::Signal() { if (!SetEvent(fEvent)) { jack_error("JackWinProcessSync::Signal SetEvent err = %d", GetLastError()); } } void JackWinProcessSync::LockedSignal() { DWORD res = WaitForSingleObject(fMutex, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::LockedSignal WaitForSingleObject err = %d", GetLastError()); } if (!SetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedSignal SetEvent err = %d", GetLastError()); } if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::LockedSignal ReleaseMutex err = %d", GetLastError()); } } void JackWinProcessSync::SignalAll() { Signal(); } void JackWinProcessSync::LockedSignalAll() { LockedSignal(); } /* void JackWinProcessSync::Wait() { if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::Wait ReleaseMutex err = %d", GetLastError()); } DWORD res = WaitForSingleObject(fEvent, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::Wait WaitForSingleObject err = %d", GetLastError()); } } */ void JackWinProcessSync::LockedWait() { // Does it make sense on Windows, use non-locked version for now... Wait(); } /* bool JackWinProcessSync::TimedWait(long usec) { if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::TimedWait ReleaseMutex err = %d", GetLastError()); } DWORD res = WaitForSingleObject(fEvent, usec / 1000); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); } return (res == WAIT_OBJECT_0); } */ bool JackWinProcessSync::LockedTimedWait(long usec) { // Does it make sense on Windows, use non-locked version for now... return TimedWait(usec); } void JackWinProcessSync::Wait() { // In case Wait is called in a "locked" context if (ReleaseMutex(fMutex)) { HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::Wait WaitForMultipleObjects err = %d", GetLastError()); } // In case Wait is called in a "non-locked" context } else { jack_error("JackWinProcessSync::Wait ReleaseMutex err = %d", GetLastError()); DWORD res = WaitForSingleObject(fEvent, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::Wait WaitForSingleObject err = %d", GetLastError()); } } if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::Wait ResetEvent err = %d", GetLastError()); } } bool JackWinProcessSync::TimedWait(long usec) { DWORD res = 0; // In case TimedWait is called in a "locked" context if (ReleaseMutex(fMutex)) { HANDLE handles[] = { fMutex, fEvent }; res = WaitForMultipleObjects(2, handles, true, usec / 1000); if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) { jack_error("JackWinProcessSync::TimedWait WaitForMultipleObjects err = %d", GetLastError()); } // In case TimedWait is called in a "non-locked" context } else { jack_error("JackWinProcessSync::TimedWait ReleaseMutex err = %d", GetLastError()); res = WaitForSingleObject(fEvent, usec / 1000); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); } } if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::TimedWait ResetEvent err = %d", GetLastError()); } return (res == WAIT_OBJECT_0); } /* // Code from APPLE CAGuard.cpp : does not seem to work as expected... void JackWinProcessSync::Wait() { if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::Wait ReleaseMutex err = %d", GetLastError()); } DWORD res = WaitForSingleObject(fEvent, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::Wait WaitForSingleObject err = %d", GetLastError()); } } // Variant that behaves differently depending of the mutex state void JackWinProcessSync::Wait() { if (ReleaseMutex(fMutex)) { HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::LockedWait WaitForMultipleObjects err = %d", GetLastError()); } } else { jack_error("JackWinProcessSync::Wait ReleaseMutex err = %d", GetLastError()); DWORD res = WaitForSingleObject(fEvent, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::Wait WaitForSingleObject err = %d", GetLastError()); } } if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedWait ResetEvent err = %d", GetLastError()); } } void JackWinProcessSync::LockedWait() { if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::LockedWait ReleaseMutex err = %d", GetLastError()); } HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::LockedWait WaitForMultipleObjects err = %d", GetLastError()); } if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedWait ResetEvent err = %d", GetLastError()); } } bool JackWinProcessSync::TimedWait(long usec) { if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::TimedWait ReleaseMutex err = %d", GetLastError()); } DWORD res = WaitForSingleObject(fEvent, usec / 1000); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); } return (res == WAIT_OBJECT_0); } // Variant that behaves differently depending of the mutex state bool JackWinProcessSync::TimedWait(long usec) { if (ReleaseMutex(fMutex)) { HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, usec / 1000); if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) { jack_error("JackWinProcessSync::LockedTimedWait WaitForMultipleObjects err = %d", GetLastError()); } } else { jack_error("JackWinProcessSync::TimedWait ReleaseMutex err = %d", GetLastError()); DWORD res = WaitForSingleObject(fEvent, usec / 1000); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); } } if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedTimedWait ResetEvent err = %d", GetLastError()); } return (res == WAIT_OBJECT_0); } bool JackWinProcessSync::LockedTimedWait(long usec) { if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::LockedTimedWait ReleaseMutex err = %d", GetLastError()); } HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, usec / 1000); if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) { jack_error("JackWinProcessSync::LockedTimedWait WaitForMultipleObjects err = %d", GetLastError()); } if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedTimedWait ResetEvent err = %d", GetLastError()); } return (res == WAIT_OBJECT_0); } */ } // end of namespace 1.9.12~dfsg/windows/jack_test.cbp0000644000000000000000000001234113214314510015470 0ustar rootroot 1.9.12~dfsg/windows/Release/0000755000000000000000000000000013214314510014412 5ustar rootroot1.9.12~dfsg/windows/Release/bin/0000755000000000000000000000000013244556535015204 5ustar rootroot1.9.12~dfsg/windows/JackSystemDeps_os.h0000644000000000000000000000333413214314510016600 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSystemDeps_WIN32__ #define __JackSystemDeps_WIN32__ #include #include "JackCompilerDeps.h" #ifndef PATH_MAX #define PATH_MAX 512 #endif #define UINT32_MAX 4294967295U #define DRIVER_HANDLE HINSTANCE #define LoadDriverModule(name) LoadLibrary((name)) #define UnloadDriverModule(handle) (FreeLibrary(((HMODULE)handle))) #define GetDriverProc(handle, name) GetProcAddress(((HMODULE)handle), (name)) #define JACK_HANDLE HINSTANCE #define LoadJackModule(name) LoadLibrary((name)); #define UnloadJackModule(handle) FreeLibrary((handle)); #define GetJackProc(handle, name) GetProcAddress((handle), (name)); #ifndef ENOBUFS #define ENOBUFS 55 #endif #ifdef _DEBUG #define JACK_DEBUG true #else #define JACK_DEBUG false #endif inline int setenv(const char* name, const char* value, int overwrite) { if (overwrite == 0 && getenv(name) != NULL) { return 0; } return _putenv_s(name, value); } inline int unsetenv(const char* name) { return _putenv_s(name, ""); } #endif 1.9.12~dfsg/windows/jack_lsp.cbp0000644000000000000000000001130313214314510015304 0ustar rootroot 1.9.12~dfsg/windows/JackWinMutex.h0000644000000000000000000000517013214314510015557 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinMutex__ #define __JackWinMutex__ #include "JackCompilerDeps.h" #include "JackException.h" #include #include namespace Jack { /*! \brief Mutex abstraction. */ class SERVER_EXPORT JackBaseWinMutex { protected: HANDLE fMutex; DWORD fOwner; public: JackBaseWinMutex():fOwner(0) { // In recursive mode by default fMutex = CreateMutex(NULL, FALSE, NULL); ThrowIf((fMutex == 0), JackException("JackBaseWinMutex: could not init the mutex")); } virtual ~JackBaseWinMutex() { CloseHandle(fMutex); } bool Lock(); bool Trylock(); bool Unlock(); }; class SERVER_EXPORT JackWinMutex { protected: HANDLE fMutex; public: JackWinMutex(const char* name = NULL) { // In recursive mode by default if (name) { char buffer[MAX_PATH]; snprintf(buffer, sizeof(buffer), "%s_%s", "JackWinMutex", name); fMutex = CreateMutex(NULL, FALSE, buffer); } else { fMutex = CreateMutex(NULL, FALSE, NULL); } ThrowIf((fMutex == 0), JackException("JackWinMutex: could not init the mutex")); } virtual ~JackWinMutex() { CloseHandle(fMutex); } bool Lock(); bool Trylock(); bool Unlock(); }; class SERVER_EXPORT JackWinCriticalSection { protected: CRITICAL_SECTION fSection; public: JackWinCriticalSection(const char* name = NULL) { InitializeCriticalSection(&fSection); } virtual ~JackWinCriticalSection() { DeleteCriticalSection(&fSection); } bool Lock(); bool Trylock(); bool Unlock(); }; } // namespace #endif 1.9.12~dfsg/windows/jackd.workspace0000644000000000000000000000232013214314510016023 0ustar rootroot 1.9.12~dfsg/windows/winmme/0000755000000000000000000000000013214314510014326 5ustar rootroot1.9.12~dfsg/windows/winmme/JackWinMMEInputPort.h0000644000000000000000000000425313214314510020255 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackWinMMEInputPort__ #define __JackWinMMEInputPort__ #include #include "JackMidiAsyncQueue.h" #include "JackMidiBufferWriteQueue.h" #include "JackWinMMEPort.h" namespace Jack { class JackWinMMEInputPort : public JackWinMMEPort { private: static void CALLBACK HandleMidiInputEvent(HMIDIIN handle, UINT message, DWORD port, DWORD param1, DWORD param2); void EnqueueMessage(DWORD timestamp, size_t length, jack_midi_data_t *data); void GetInErrorString(MMRESULT error, LPTSTR text); void ProcessWinMME(UINT message, DWORD param1, DWORD param2); void WriteInError(const char *jack_func, const char *mm_func, MMRESULT result); HMIDIIN handle; jack_midi_event_t *jack_event; jack_time_t start_time; bool started; jack_midi_data_t *sysex_buffer; MIDIHDR sysex_header; JackMidiAsyncQueue *thread_queue; JackMidiBufferWriteQueue *write_queue; public: JackWinMMEInputPort(const char *alias_name, const char *client_name, const char *driver_name, UINT index, size_t max_bytes=4096, size_t max_messages=1024); ~JackWinMMEInputPort(); void ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); bool Start(); bool Stop(); }; } #endif 1.9.12~dfsg/windows/winmme/JackWinMMEDriver.h0000644000000000000000000000330113214314510017535 0ustar rootroot/* Copyright (C) 2009 Grame Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackWinMMEDriver__ #define __JackWinMMEDriver__ #include "JackMidiDriver.h" #include "JackWinMMEInputPort.h" #include "JackWinMMEOutputPort.h" namespace Jack { class JackWinMMEDriver : public JackMidiDriver { private: JackWinMMEInputPort **input_ports; JackWinMMEOutputPort **output_ports; UINT period; public: JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); ~JackWinMMEDriver(); int Attach(); int Close(); int Open(bool capturing, bool playing, int num_inputs, int num_outputs, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); int Read(); int Start(); int Stop(); int Write(); }; } #endif 1.9.12~dfsg/windows/winmme/JackWinMMEInputPort.cpp0000644000000000000000000002600513214314510020607 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "JackError.h" #include "JackTime.h" #include "JackMidiUtil.h" #include "JackWinMMEInputPort.h" #include "JackMidiWriteQueue.h" using Jack::JackWinMMEInputPort; /////////////////////////////////////////////////////////////////////////////// // Static callbacks /////////////////////////////////////////////////////////////////////////////// void CALLBACK JackWinMMEInputPort::HandleMidiInputEvent(HMIDIIN handle, UINT message, DWORD port, DWORD param1, DWORD param2) { ((JackWinMMEInputPort *) port)->ProcessWinMME(message, param1, param2); } /////////////////////////////////////////////////////////////////////////////// // Class /////////////////////////////////////////////////////////////////////////////// JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, const char *client_name, const char *driver_name, UINT index, size_t max_bytes, size_t max_messages) { thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); std::auto_ptr thread_queue_ptr(thread_queue); write_queue = new JackMidiBufferWriteQueue(); std::auto_ptr write_queue_ptr(write_queue); sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; MMRESULT result = midiInOpen(&handle, index, (DWORD_PTR) HandleMidiInputEvent, (DWORD_PTR)this, CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { GetInErrorString(result, error_message); goto delete_sysex_buffer; } sysex_header.dwBufferLength = max_bytes; sysex_header.dwFlags = 0; sysex_header.lpData = (LPSTR)sysex_buffer; result = midiInPrepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { GetInErrorString(result, error_message); goto close_handle; } result = midiInAddBuffer(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { GetInErrorString(result, error_message); goto unprepare_header; } MIDIINCAPS capabilities; char *name_tmp; result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", result); name_tmp = (char*) driver_name; } else { name_tmp = capabilities.szPname; } snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", alias_name, name_tmp, index + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); jack_event = 0; started = false; write_queue_ptr.release(); thread_queue_ptr.release(); return; unprepare_header: result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [constructor]", "midiInUnprepareHeader", result); } close_handle: result = midiInClose(handle); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [constructor]", "midiInClose", result); } delete_sysex_buffer: delete[] sysex_buffer; throw std::runtime_error(error_message); } JackWinMMEInputPort::~JackWinMMEInputPort() { MMRESULT result = midiInReset(handle); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [destructor]", "midiInReset", result); } result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", result); } result = midiInClose(handle); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [destructor]", "midiInClose", result); } delete[] sysex_buffer; delete thread_queue; delete write_queue; } void JackWinMMEInputPort::EnqueueMessage(DWORD timestamp, size_t length, jack_midi_data_t *data) { jack_nframes_t frame = GetFramesFromTime(start_time + (((jack_time_t) timestamp) * 1000)); // Debugging code jack_time_t current_time = GetMicroSeconds(); jack_log("JackWinMMEInputPort::EnqueueMessage - enqueueing event at %f " "(frame: %d) with start offset '%d' scheduled for frame '%d'", ((double) current_time) / 1000.0, GetFramesFromTime(current_time), timestamp, frame); // End debugging code switch (thread_queue->EnqueueEvent(frame, length, data)) { case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " "cannot currently accept a %d-byte event. Dropping event.", length); break; case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " "buffer is too small to enqueue a %d-byte event. Dropping " "event.", length); break; default: ; } } void JackWinMMEInputPort::GetInErrorString(MMRESULT error, LPTSTR text) { MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); if (result != MMSYSERR_NOERROR) { snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); } } void JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { write_queue->ResetMidiBuffer(port_buffer, frames); if (! jack_event) { jack_event = thread_queue->DequeueEvent(); } for (; jack_event; jack_event = thread_queue->DequeueEvent()) { switch (write_queue->EnqueueEvent(jack_event, frames)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEMidiInputPort::Process - The buffer write " "queue couldn't enqueue a %d-byte event. Dropping " "event.", jack_event->size); // Fallthrough on purpose case JackMidiWriteQueue::OK: continue; default: break; } break; } } void JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) { set_threaded_log_function(); switch (message) { case MIM_CLOSE: jack_log("JackWinMMEInputPort::ProcessWinMME - MIDI device closed."); break; case MIM_MOREDATA: jack_log("JackWinMMEInputPort::ProcessWinMME - The MIDI input device " "driver thinks that JACK is not processing messages fast " "enough."); // Fallthrough on purpose. case MIM_DATA: { jack_midi_data_t message_buffer[3]; jack_midi_data_t status = param1 & 0xff; int length = GetMessageLength(status); switch (length) { case 3: message_buffer[2] = (param1 >> 16) & 0xff; // Fallthrough on purpose. case 2: message_buffer[1] = (param1 >> 8) & 0xff; // Fallthrough on purpose. case 1: message_buffer[0] = status; break; case 0: jack_error("JackWinMMEInputPort::ProcessWinMME - **BUG** MIDI " "input driver sent an MIM_DATA message with a sysex " "status byte."); return; case -1: jack_error("JackWinMMEInputPort::ProcessWinMME - **BUG** MIDI " "input driver sent an MIM_DATA message with an invalid " "status byte."); return; } EnqueueMessage(param2, (size_t) length, message_buffer); break; } case MIM_LONGDATA: { LPMIDIHDR header = (LPMIDIHDR) param1; size_t byte_count = header->dwBytesRecorded; if (! byte_count) { jack_log("JackWinMMEInputPort::ProcessWinMME - WinMME driver has " "returned sysex header to us with no bytes. The JACK " "driver is probably being stopped."); break; } jack_midi_data_t *data = (jack_midi_data_t *) header->lpData; if ((data[0] != 0xf0) || (data[byte_count - 1] != 0xf7)) { jack_error("JackWinMMEInputPort::ProcessWinMME - Discarding " "%d-byte sysex chunk.", byte_count); } else { EnqueueMessage(param2, byte_count, data); } // Is this realtime-safe? This function isn't run in the JACK thread, // but we still want it to perform as quickly as possible. Even if // this isn't realtime safe, it may not be avoidable. MMRESULT result = midiInAddBuffer(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort::ProcessWinMME", "midiInAddBuffer", result); } break; } case MIM_LONGERROR: jack_error("JackWinMMEInputPort::ProcessWinMME - Invalid or " "incomplete sysex message received."); break; case MIM_OPEN: jack_log("JackWinMMEInputPort::ProcessWinMME - MIDI device opened."); } } bool JackWinMMEInputPort::Start() { if (! started) { start_time = GetMicroSeconds(); MMRESULT result = midiInStart(handle); started = result == MMSYSERR_NOERROR; if (! started) { WriteInError("JackWinMMEInputPort::Start", "midiInStart", result); } } return started; } bool JackWinMMEInputPort::Stop() { if (started) { MMRESULT result = midiInStop(handle); started = result != MMSYSERR_NOERROR; if (started) { WriteInError("JackWinMMEInputPort::Stop", "midiInStop", result); } } return ! started; } void JackWinMMEInputPort::WriteInError(const char *jack_func, const char *mm_func, MMRESULT result) { char error_message[MAXERRORLENGTH]; GetInErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } 1.9.12~dfsg/windows/winmme/JackWinMMEPort.cpp0000644000000000000000000000341213214314510017564 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "JackWinMMEPort.h" #include "JackError.h" using Jack::JackWinMMEPort; /////////////////////////////////////////////////////////////////////////////// // Class /////////////////////////////////////////////////////////////////////////////// JackWinMMEPort::JackWinMMEPort() {} JackWinMMEPort::~JackWinMMEPort() {} const char * JackWinMMEPort::GetAlias() { return alias; } const char * JackWinMMEPort::GetName() { return name; } void JackWinMMEPort::GetOSErrorString(LPTSTR text) { DWORD error = GetLastError(); if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), text, MAXERRORLENGTH, NULL)) { snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%ld'", error); } } void JackWinMMEPort::WriteOSError(const char *jack_func, const char *os_func) { char error_message[MAXERRORLENGTH]; GetOSErrorString(error_message); jack_error("%s - %s: %s", jack_func, os_func, error_message); } 1.9.12~dfsg/windows/winmme/JackWinMMEOutputPort.cpp0000644000000000000000000003247313214314510021016 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackMidiUtil.h" #include "JackTime.h" #include "JackWinMMEOutputPort.h" #include "JackGlobals.h" #include "JackEngineControl.h" using Jack::JackWinMMEOutputPort; /////////////////////////////////////////////////////////////////////////////// // Static callbacks /////////////////////////////////////////////////////////////////////////////// void CALLBACK JackWinMMEOutputPort::HandleMessageEvent(HMIDIOUT handle, UINT message, DWORD_PTR port, DWORD_PTR param1, DWORD_PTR param2) { ((JackWinMMEOutputPort *) port)->HandleMessage(message, param1, param2); } /////////////////////////////////////////////////////////////////////////////// // Class /////////////////////////////////////////////////////////////////////////////// JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, const char *client_name, const char *driver_name, UINT index, size_t max_bytes, size_t max_messages) { read_queue = new JackMidiBufferReadQueue(); std::auto_ptr read_queue_ptr(read_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); std::auto_ptr thread_queue_ptr(thread_queue); thread = new JackThread(this); std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; MMRESULT result = midiOutOpen(&handle, index, (DWORD_PTR)HandleMessageEvent, (DWORD_PTR)this, CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { GetOutErrorString(result, error_message); goto raise_exception; } thread_queue_semaphore = CreateSemaphore(NULL, 0, max_messages, NULL); if (thread_queue_semaphore == NULL) { GetOSErrorString(error_message); goto close_handle; } sysex_semaphore = CreateSemaphore(NULL, 0, 1, NULL); if (sysex_semaphore == NULL) { GetOSErrorString(error_message); goto destroy_thread_queue_semaphore; } MIDIOUTCAPS capabilities; char *name_tmp; result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); name_tmp = (char*)driver_name; } else { name_tmp = capabilities.szPname; } snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, name_tmp, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); read_queue_ptr.release(); thread_queue_ptr.release(); thread_ptr.release(); return; destroy_thread_queue_semaphore: if (! CloseHandle(thread_queue_semaphore)) { WriteOSError("JackWinMMEOutputPort [constructor]", "CloseHandle"); } close_handle: result = midiOutClose(handle); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutClose", result); } raise_exception: throw std::runtime_error(error_message); } JackWinMMEOutputPort::~JackWinMMEOutputPort() { MMRESULT result = midiOutReset(handle); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort [destructor]", "midiOutReset", result); } result = midiOutClose(handle); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort [destructor]", "midiOutClose", result); } if (! CloseHandle(sysex_semaphore)) { WriteOSError("JackWinMMEOutputPort [destructor]", "CloseHandle"); } if (! CloseHandle(thread_queue_semaphore)) { WriteOSError("JackWinMMEOutputPort [destructor]", "CloseHandle"); } delete read_queue; delete thread_queue; delete thread; } bool JackWinMMEOutputPort::Execute() { for (;;) { if (! Wait(thread_queue_semaphore)) { jack_log("JackWinMMEOutputPort::Execute BREAK"); break; } jack_midi_event_t *event = thread_queue->DequeueEvent(); if (! event) { break; } jack_time_t frame_time = GetTimeFromFrames(event->time); jack_time_t current_time = GetMicroSeconds(); if (frame_time > current_time) { LARGE_INTEGER due_time; // 100 ns resolution due_time.QuadPart = -((LONGLONG) ((frame_time - current_time) * 10)); if (! SetWaitableTimer(timer, &due_time, 0, NULL, NULL, 0)) { WriteOSError("JackWinMMEOutputPort::Execute", "SetWaitableTimer"); break; } // Debugging code jack_log("JackWinMMEOutputPort::Execute - waiting at %f for %f " "milliseconds before sending message (current frame: %d, " "send frame: %d)", ((double) current_time) / 1000.0, ((double) (frame_time - current_time)) / 1000.0, GetFramesFromTime(current_time), event->time); // End debugging code if (! Wait(timer)) { break; } // Debugging code jack_time_t wakeup_time = GetMicroSeconds(); jack_log("JackWinMMEOutputPort::Execute - woke up at %f.", ((double) wakeup_time) / 1000.0); if (wakeup_time > frame_time) { jack_log("JackWinMMEOutputPort::Execute - overslept by %f " "milliseconds.", ((double) (wakeup_time - frame_time)) / 1000.0); } else if (wakeup_time < frame_time) { jack_log("JackWinMMEOutputPort::Execute - woke up %f " "milliseconds too early.", ((double) (frame_time - wakeup_time)) / 1000.0); } // End debugging code } jack_midi_data_t *data = event->buffer; DWORD message = 0; MMRESULT result; size_t size = event->size; switch (size) { case 3: message |= (((DWORD) data[2]) << 16); // Fallthrough on purpose. case 2: message |= (((DWORD) data[1]) << 8); // Fallthrough on purpose. case 1: message |= (DWORD) data[0]; result = midiOutShortMsg(handle, message); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort::Execute", "midiOutShortMsg", result); } continue; } MIDIHDR header; header.dwBufferLength = size; header.dwFlags = 0; header.lpData = (LPSTR) data; result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort::Execute", "midiOutPrepareHeader", result); continue; } result = midiOutLongMsg(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort::Execute", "midiOutLongMsg", result); continue; } // System exclusive messages may be sent synchronously or // asynchronously. The choice is up to the WinMME driver. So, we wait // until the message is sent, regardless of the driver's choice. if (! Wait(sysex_semaphore)) { break; } result = midiOutUnprepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort::Execute", "midiOutUnprepareHeader", result); break; } } return false; } void JackWinMMEOutputPort::GetOutErrorString(MMRESULT error, LPTSTR text) { MMRESULT result = midiOutGetErrorText(error, text, MAXERRORLENGTH); if (result != MMSYSERR_NOERROR) { snprintf(text, MAXERRORLENGTH, "Unknown MM error code '%d'", error); } } void JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2) { set_threaded_log_function(); switch (message) { case MOM_CLOSE: jack_log("JackWinMMEOutputPort::HandleMessage - MIDI device closed."); break; case MOM_DONE: Signal(sysex_semaphore); break; case MOM_OPEN: jack_log("JackWinMMEOutputPort::HandleMessage - MIDI device opened."); break; case MOM_POSITIONCB: LPMIDIHDR header = (LPMIDIHDR) param1; jack_log("JackWinMMEOutputPort::HandleMessage - %d bytes out of %d " "bytes of the current sysex message have been sent.", header->dwOffset, header->dwBytesRecorded); } } bool JackWinMMEOutputPort::Init() { set_threaded_log_function(); // XX: Can more be done? Ideally, this thread should have the JACK server // thread priority + 1. if (thread->AcquireSelfRealTime(GetEngineControl()->fServerPriority)) { jack_error("JackWinMMEOutputPort::Init - could not acquire realtime " "scheduling. Continuing anyway."); } return true; } void JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { read_queue->ResetMidiBuffer(port_buffer); for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; event = read_queue->DequeueEvent()) { switch (thread_queue->EnqueueEvent(event, frames)) { case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackWinMMEOutputPort::ProcessJack - The thread queue " "buffer is full. Dropping event."); break; case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEOutputPort::ProcessJack - The thread queue " "couldn't enqueue a %d-byte event. Dropping event.", event->size); break; default: Signal(thread_queue_semaphore); } } } bool JackWinMMEOutputPort::Signal(HANDLE semaphore) { bool result = (bool) ReleaseSemaphore(semaphore, 1, NULL); if (! result) { WriteOSError("JackWinMMEOutputPort::Signal", "ReleaseSemaphore"); } return result; } bool JackWinMMEOutputPort::Start() { if (thread->GetStatus() != JackThread::kIdle) { return true; } timer = CreateWaitableTimer(NULL, FALSE, NULL); if (! timer) { WriteOSError("JackWinMMEOutputPort::Start", "CreateWaitableTimer"); return false; } if (! thread->StartSync()) { return true; } jack_error("JackWinMMEOutputPort::Start - failed to start MIDI processing " "thread."); if (! CloseHandle(timer)) { WriteOSError("JackWinMMEOutputPort::Start", "CloseHandle"); } return false; } bool JackWinMMEOutputPort::Stop() { jack_log("JackWinMMEOutputPort::Stop - stopping MIDI output port " "processing thread."); int result; const char *verb; switch (thread->GetStatus()) { case JackThread::kIniting: case JackThread::kStarting: result = thread->Kill(); verb = "kill"; break; case JackThread::kRunning: Signal(thread_queue_semaphore); result = thread->Stop(); verb = "stop"; break; default: return true; } if (result) { jack_error("JackWinMMEOutputPort::Stop - could not %s MIDI processing " "thread.", verb); } if (! CloseHandle(timer)) { WriteOSError("JackWinMMEOutputPort::Stop", "CloseHandle"); result = -1; } return ! result; } bool JackWinMMEOutputPort::Wait(HANDLE semaphore) { DWORD result = WaitForSingleObject(semaphore, INFINITE); switch (result) { case WAIT_FAILED: WriteOSError("JackWinMMEOutputPort::Wait", "WaitForSingleObject"); break; case WAIT_OBJECT_0: return true; default: jack_error("JackWinMMEOutputPort::Wait - unexpected result from " "'WaitForSingleObject'."); } return false; } void JackWinMMEOutputPort::WriteOutError(const char *jack_func, const char *mm_func, MMRESULT result) { char error_message[MAXERRORLENGTH]; GetOutErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } 1.9.12~dfsg/windows/winmme/JackWinMMEPort.h0000644000000000000000000000241213214314510017230 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackWinMMEPort__ #define __JackWinMMEPort__ #include #include #include "JackConstants.h" namespace Jack { class JackWinMMEPort { protected: char alias[REAL_JACK_PORT_NAME_SIZE+1]; char name[REAL_JACK_PORT_NAME_SIZE+1]; public: JackWinMMEPort(); ~JackWinMMEPort(); const char * GetAlias(); const char * GetName(); void GetOSErrorString(LPTSTR text); void WriteOSError(const char *jack_func, const char *os_func); }; } #endif 1.9.12~dfsg/windows/winmme/JackWinMMEDriver.cpp0000644000000000000000000003276113214314510020104 0ustar rootroot/* Copyright (C) 2009 Grame Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "JackEngineControl.h" #include "JackWinMMEDriver.h" #include "driver_interface.h" using Jack::JackWinMMEDriver; JackWinMMEDriver::JackWinMMEDriver(const char *name, const char *alias, JackLockedEngine *engine, JackSynchro *table): JackMidiDriver(name, alias, engine, table) { input_ports = 0; output_ports = 0; period = 0; } JackWinMMEDriver::~JackWinMMEDriver() {} int JackWinMMEDriver::Attach() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; jack_port_id_t index; jack_nframes_t latency = buffer_size; jack_latency_range_t latency_range; const char *name; JackPort *port; latency_range.max = latency + ((jack_nframes_t) std::ceil((period / 1000.0) * fEngineControl->fSampleRate)); latency_range.min = latency; jack_log("JackWinMMEDriver::Attach - fCaptureChannels %d", fCaptureChannels); jack_log("JackWinMMEDriver::Attach - fPlaybackChannels %d", fPlaybackChannels); // Inputs for (int i = 0; i < fCaptureChannels; i++) { JackWinMMEInputPort *input_port = input_ports[i]; name = input_port->GetName(); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, buffer_size, &index) < 0) { jack_error("JackWinMMEDriver::Attach - cannot register input port " "with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(input_port->GetAlias()); port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[i] = index; } if (! fEngineControl->fSyncMode) { latency += buffer_size; latency_range.max = latency; latency_range.min = latency; } // Outputs for (int i = 0; i < fPlaybackChannels; i++) { JackWinMMEOutputPort *output_port = output_ports[i]; name = output_port->GetName(); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, buffer_size, &index) < 0) { jack_error("JackWinMMEDriver::Attach - cannot register output " "port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(output_port->GetAlias()); port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[i] = index; } return 0; } int JackWinMMEDriver::Close() { // Generic MIDI driver close int result = JackMidiDriver::Close(); if (input_ports) { for (int i = 0; i < fCaptureChannels; i++) { delete input_ports[i]; } delete[] input_ports; input_ports = 0; } if (output_ports) { for (int i = 0; i < fPlaybackChannels; i++) { delete output_ports[i]; } delete[] output_ports; output_ports = 0; } if (period) { if (timeEndPeriod(period) != TIMERR_NOERROR) { jack_error("JackWinMMEDriver::Close - failed to unset timer " "resolution."); result = -1; } } return result; } int JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, int out_channels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { const char *client_name = fClientControl.fName; int input_count = 0; int output_count = 0; int num_potential_inputs = midiInGetNumDevs(); int num_potential_outputs = midiOutGetNumDevs(); jack_log("JackWinMMEDriver::Open - num_potential_inputs %d", num_potential_inputs); jack_log("JackWinMMEDriver::Open - num_potential_outputs %d", num_potential_outputs); period = 0; TIMECAPS caps; if (timeGetDevCaps(&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) { jack_error("JackWinMMEDriver::Open - could not get timer device " "capabilities. Continuing anyway ..."); } else { period = caps.wPeriodMin; if (timeBeginPeriod(period) != TIMERR_NOERROR) { jack_error("JackWinMMEDriver::Open - could not set minimum timer " "resolution. Continuing anyway ..."); period = 0; } else { jack_log("JackWinMMEDriver::Open - multimedia timer resolution " "set to %d milliseconds.", period); } } if (num_potential_inputs) { try { input_ports = new JackWinMMEInputPort *[num_potential_inputs]; } catch (std::exception& e) { jack_error("JackWinMMEDriver::Open - while creating input port " "array: %s", e.what()); goto unset_timer_resolution; } for (int i = 0; i < num_potential_inputs; i++) { try { input_ports[input_count] = new JackWinMMEInputPort(fAliasName, client_name, capture_driver_name, i); } catch (std::exception& e) { jack_error("JackWinMMEDriver::Open - while creating input " "port: %s", e.what()); continue; } input_count++; } } if (num_potential_outputs) { try { output_ports = new JackWinMMEOutputPort *[num_potential_outputs]; } catch (std::exception& e) { jack_error("JackWinMMEDriver::Open - while creating output port " "array: %s", e.what()); goto destroy_input_ports; } for (int i = 0; i < num_potential_outputs; i++) { try { output_ports[output_count] = new JackWinMMEOutputPort(fAliasName, client_name, playback_driver_name, i); } catch (std::exception& e) { jack_error("JackWinMMEDriver::Open - while creating output " "port: %s", e.what()); continue; } output_count++; } } jack_log("JackWinMMEDriver::Open - input_count %d", input_count); jack_log("JackWinMMEDriver::Open - output_count %d", output_count); if (! (input_count || output_count)) { jack_error("JackWinMMEDriver::Open - no WinMME inputs or outputs " "allocated."); } else if (! JackMidiDriver::Open(capturing, playing, input_count, output_count, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency)) { return 0; } if (output_ports) { for (int i = 0; i < output_count; i++) { delete output_ports[i]; } delete[] output_ports; output_ports = 0; } destroy_input_ports: if (input_ports) { for (int i = 0; i < input_count; i++) { delete input_ports[i]; } delete[] input_ports; input_ports = 0; } unset_timer_resolution: if (period) { if (timeEndPeriod(period) != TIMERR_NOERROR) { jack_error("JackWinMMEDriver::Open - failed to unset timer " "resolution."); } } return -1; } int JackWinMMEDriver::Read() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fCaptureChannels; i++) { input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); } return 0; } int JackWinMMEDriver::Write() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fPlaybackChannels; i++) { output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); } return 0; } int JackWinMMEDriver::Start() { jack_log("JackWinMMEDriver::Start - Starting driver."); JackMidiDriver::Start(); int input_count = 0; int output_count = 0; jack_log("JackWinMMEDriver::Start - Enabling input ports."); for (; input_count < fCaptureChannels; input_count++) { if (input_ports[input_count]->Start() < 0) { jack_error("JackWinMMEDriver::Start - Failed to enable input " "port."); goto stop_input_ports; } } jack_log("JackWinMMEDriver::Start - Enabling output ports."); for (; output_count < fPlaybackChannels; output_count++) { if (output_ports[output_count]->Start() < 0) { jack_error("JackWinMMEDriver::Start - Failed to enable output " "port."); goto stop_output_ports; } } jack_log("JackWinMMEDriver::Start - Driver started."); return 0; stop_output_ports: for (int i = 0; i < output_count; i++) { if (output_ports[i]->Stop() < 0) { jack_error("JackWinMMEDriver::Start - Failed to disable output " "port."); } } stop_input_ports: for (int i = 0; i < input_count; i++) { if (input_ports[i]->Stop() < 0) { jack_error("JackWinMMEDriver::Start - Failed to disable input " "port."); } } return -1; } int JackWinMMEDriver::Stop() { int result = 0; JackMidiDriver::Stop(); jack_log("JackWinMMEDriver::Stop - disabling input ports."); for (int i = 0; i < fCaptureChannels; i++) { if (input_ports[i]->Stop() < 0) { jack_error("JackWinMMEDriver::Stop - Failed to disable input " "port."); result = -1; } } jack_log("JackWinMMEDriver::Stop - disabling output ports."); for (int i = 0; i < fPlaybackChannels; i++) { if (output_ports[i]->Stop() < 0) { jack_error("JackWinMMEDriver::Stop - Failed to disable output " "port."); result = -1; } } return result; } #ifdef __cplusplus extern "C" { #endif // singleton kind of driver static Jack::JackWinMMEDriver* driver = NULL; SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() { return jack_driver_descriptor_construct("winmme", JackDriverSlave, "WinMME API based MIDI backend", NULL); } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { /* unsigned int capture_ports = 2; unsigned int playback_ports = 2; unsigned long wait_time = 0; const JSList * node; const jack_driver_param_t * param; bool monitor = false; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'C': capture_ports = param->value.ui; break; case 'P': playback_ports = param->value.ui; break; case 'r': sample_rate = param->value.ui; break; case 'p': period_size = param->value.ui; break; case 'w': wait_time = param->value.ui; break; case 'm': monitor = param->value.i; break; } } */ // singleton kind of driver if (!driver) { driver = new Jack::JackWinMMEDriver("system_midi", "winmme", engine, table); if (driver->Open(1, 1, 0, 0, false, "in", "out", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } else { jack_info("JackWinMMEDriver already allocated, cannot be loaded twice"); return NULL; } } #ifdef __cplusplus } #endif /* jack_connect system:midi_capture_1 system_midi:playback_1 jack_connect system:midi_capture_1 system_midi:playback_2 jack_connect system:midi_capture_1 system_midi:playback_1 jack_connect system:midi_capture_1 system_midi:playback_1 jack_connect system:midi_capture_1 system_midi:playback_1 jack_connect system_midi:capture_1 system:midi_playback_1 jack_connect system_midi:capture_2 system:midi_playback_1 jack_connect system_midi:capture_1 system_midi:playback_1 */ 1.9.12~dfsg/windows/winmme/JackWinMMEOutputPort.h0000644000000000000000000000440613214314510020456 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackWinMMEOutputPort__ #define __JackWinMMEOutputPort__ #include "JackMidiAsyncQueue.h" #include "JackMidiBufferReadQueue.h" #include "JackThread.h" #include "JackWinMMEPort.h" namespace Jack { class JackWinMMEOutputPort : public JackWinMMEPort, public JackRunnableInterface { private: static void CALLBACK HandleMessageEvent(HMIDIOUT handle, UINT message, DWORD_PTR port, DWORD_PTR param1, DWORD_PTR param2); void GetOutErrorString(MMRESULT error, LPTSTR text); void HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); bool Signal(HANDLE semaphore); bool Wait(HANDLE semaphore); void WriteOutError(const char *jack_func, const char *mm_func, MMRESULT result); HMIDIOUT handle; JackMidiBufferReadQueue *read_queue; HANDLE sysex_semaphore; JackThread *thread; JackMidiAsyncQueue *thread_queue; HANDLE thread_queue_semaphore; HANDLE timer; public: JackWinMMEOutputPort(const char *alias_name, const char *client_name, const char *driver_name, UINT index, size_t max_bytes=4096, size_t max_messages=1024); ~JackWinMMEOutputPort(); bool Execute(); bool Init(); void ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); bool Start(); bool Stop(); }; } #endif 1.9.12~dfsg/windows/getopt.c0000644000000000000000000007246313214314510014514 0ustar rootroot/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO # define _NO_PROTO #endif #ifdef HAVE_CONFIG_H # include "config.h" #endif #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ # ifndef const # define const # endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 # include # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION # define ELIDE_CODE # endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ # include # include #endif /* GNU C library. */ #ifdef VMS # include # if HAVE_STRING_H - 0 # include # endif #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ # ifdef HAVE_LIBINTL_H # include # define _(msgid) gettext (msgid) # else # define _(msgid) (msgid) # endif #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ # include # define my_index strchr #else #include /* Avoid depending on library functions or files whose names are inconsistent. */ #ifndef getenv extern char *getenv (); #endif static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ # if (!defined __STDC__ || !__STDC__) && !defined strlen /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); # endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; static int original_argc; static char *const *original_argv; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) { /* XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ original_argc = argc; original_argv = argv; } # ifdef text_set_element text_set_element (__libc_subinit, store_args_and_env); # endif /* text_set_element */ # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ char __tmp = __getopt_nonoption_flags[ch1]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) #endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined __STDC__ && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ #ifdef _LIBC /* First make sure the handling of the `__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else { memset (__mempcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined __STDC__ && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #ifdef _LIBC if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { if (nonoption_flags_max_len == 0) { if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') nonoption_flags_max_len = -1; else { const char *orig_str = __getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen (orig_str); if (nonoption_flags_max_len < argc) nonoption_flags_max_len = argc; __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len); if (__getopt_nonoption_flags == NULL) nonoption_flags_max_len = -1; else memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), '\0', nonoption_flags_max_len - len); } } nonoption_flags_len = nonoption_flags_max_len; } else nonoption_flags_len = 0; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0 || !__getopt_initialized) { if (optind == 0) optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring); __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #ifdef _LIBC # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && __getopt_nonoption_flags[optind] == '1')) #else # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ 1.9.12~dfsg/windows/jack_winmme.cbp0000644000000000000000000001666413214314510016021 0ustar rootroot 1.9.12~dfsg/windows/jack_netadapter.cbp0000644000000000000000000001437613214314510016652 0ustar rootroot 1.9.12~dfsg/windows/resource_vc.h0000644000000000000000000000061413214314510015523 0ustar rootroot//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by resource.rc // // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif 1.9.12~dfsg/windows/JackWinNamedPipeClientChannel.h0000644000000000000000000000354313214314510020751 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinNamedPipeClientChannel__ #define __JackWinNamedPipeClientChannel__ #include "JackGenericClientChannel.h" #include "JackWinNamedPipe.h" #include "JackPlatformPlug.h" #include "JackThread.h" namespace Jack { class JackClient; /*! \brief JackClientChannel using pipes. */ class JackWinNamedPipeClientChannel : public JackGenericClientChannel, public JackRunnableInterface { private: JackWinNamedPipeServer fNotificationListenPipe; // Pipe listener for server notification JackThread fThread; // Thread to execute the event loop JackClient* fClient; public: JackWinNamedPipeClientChannel(); virtual ~JackWinNamedPipeClientChannel(); int Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status); void Close(); int Start(); void Stop(); // JackRunnableInterface interface bool Init(); bool Execute(); bool IsChannelThread() { return fThread.IsThread(); } }; } // end of namespace #endif 1.9.12~dfsg/windows/portaudio/0000755000000000000000000000000013214314510015040 5ustar rootroot1.9.12~dfsg/windows/portaudio/portaudio.h0000644000000000000000000013246713214314510017234 0ustar rootroot #ifndef PORTAUDIO_H #define PORTAUDIO_H /* * $Id: portaudio.h,v 1.1.2.2 2006/06/20 14:44:48 letz Exp $ * PortAudio Portable Real-Time Audio Library * PortAudio API Header File * Latest version available at: http://www.portaudio.com/ * * Copyright (c) 1999-2002 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** @file @brief The PortAudio API. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** Retrieve the release number of the currently running PortAudio build, eg 1900. */ int Pa_GetVersion( void ); /** Retrieve a textual description of the current PortAudio build, eg "PortAudio V19-devel 13 October 2002". */ const char* Pa_GetVersionText( void ); /** Error codes returned by PortAudio functions. Note that with the exception of paNoError, all PaErrorCodes are negative. */ typedef int PaError; typedef enum PaErrorCode { paNoError = 0, paNotInitialized = -10000, paUnanticipatedHostError, paInvalidChannelCount, paInvalidSampleRate, paInvalidDevice, paInvalidFlag, paSampleFormatNotSupported, paBadIODeviceCombination, paInsufficientMemory, paBufferTooBig, paBufferTooSmall, paNullCallback, paBadStreamPtr, paTimedOut, paInternalError, paDeviceUnavailable, paIncompatibleHostApiSpecificStreamInfo, paStreamIsStopped, paStreamIsNotStopped, paInputOverflowed, paOutputUnderflowed, paHostApiNotFound, paInvalidHostApi, paCanNotReadFromACallbackStream, /**< @todo review error code name */ paCanNotWriteToACallbackStream, /**< @todo review error code name */ paCanNotReadFromAnOutputOnlyStream, /**< @todo review error code name */ paCanNotWriteToAnInputOnlyStream, /**< @todo review error code name */ paIncompatibleStreamHostApi, paBadBufferPtr } PaErrorCode; /** Translate the supplied PortAudio error code into a human readable message. */ const char *Pa_GetErrorText( PaError errorCode ); /** Library initialization function - call this before using PortAudio. This function initialises internal data structures and prepares underlying host APIs for use. This function MUST be called before using any other PortAudio API functions. If Pa_Initialize() is called multiple times, each successful call must be matched with a corresponding call to Pa_Terminate(). Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not required to be fully nested. Note that if Pa_Initialize() returns an error code, Pa_Terminate() should NOT be called. @return paNoError if successful, otherwise an error code indicating the cause of failure. @see Pa_Terminate */ PaError Pa_Initialize( void ); /** Library termination function - call this when finished using PortAudio. This function deallocates all resources allocated by PortAudio since it was initializied by a call to Pa_Initialize(). In cases where Pa_Initialise() has been called multiple times, each call must be matched with a corresponding call to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically close any PortAudio streams that are still open. Pa_Terminate() MUST be called before exiting a program which uses PortAudio. Failure to do so may result in serious resource leaks, such as audio devices not being available until the next reboot. @return paNoError if successful, otherwise an error code indicating the cause of failure. @see Pa_Initialize */ PaError Pa_Terminate( void ); /** The type used to refer to audio devices. Values of this type usually range from 0 to (Pa_DeviceCount-1), and may also take on the PaNoDevice and paUseHostApiSpecificDeviceSpecification values. @see Pa_DeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification */ typedef int PaDeviceIndex; /** A special PaDeviceIndex value indicating that no device is available, or should be used. @see PaDeviceIndex */ #define paNoDevice ((PaDeviceIndex)-1) /** A special PaDeviceIndex value indicating that the device(s) to be used are specified in the host api specific stream info structure. @see PaDeviceIndex */ #define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2) /* Host API enumeration mechanism */ /** The type used to enumerate to host APIs at runtime. Values of this type range from 0 to (Pa_GetHostApiCount()-1). @see Pa_GetHostApiCount */ typedef int PaHostApiIndex; /** Retrieve the number of available host APIs. Even if a host API is available it may have no devices available. @return A non-negative value indicating the number of available host APIs or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaHostApiIndex */ PaHostApiIndex Pa_GetHostApiCount( void ); /** Retrieve the index of the default host API. The default host API will be the lowest common denominator host API on the current platform and is unlikely to provide the best performance. @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1) indicating the default host API index or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ PaHostApiIndex Pa_GetDefaultHostApi( void ); /** Unchanging unique identifiers for each supported host API. This type is used in the PaHostApiInfo structure. The values are guaranteed to be unique and to never change, thus allowing code to be written that conditionally uses host API specific extensions. New type ids will be allocated when support for a host API reaches "public alpha" status, prior to that developers should use the paInDevelopment type id. @see PaHostApiInfo */ typedef enum PaHostApiTypeId { paInDevelopment = 0, /* use while developing support for a new host API */ paDirectSound = 1, paMME = 2, paASIO = 3, paSoundManager = 4, paCoreAudio = 5, paOSS = 7, paALSA = 8, paAL = 9, paBeOS = 10, paWDMKS = 11, paJACK = 12, paWASAPI = 13 } PaHostApiTypeId; /** A structure containing information about a particular host API. */ typedef struct PaHostApiInfo { /** this is struct version 1 */ int structVersion; /** The well known unique identifier of this host API @see PaHostApiTypeId */ PaHostApiTypeId type; /** A textual description of the host API for display on user interfaces. */ const char *name; /** The number of devices belonging to this host API. This field may be used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate all devices for this host API. @see Pa_HostApiDeviceIndexToDeviceIndex */ int deviceCount; /** The default input device for this host API. The value will be a device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice if no default input device is available. */ PaDeviceIndex defaultInputDevice; /** The default output device for this host API. The value will be a device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice if no default output device is available. */ PaDeviceIndex defaultOutputDevice; } PaHostApiInfo; /** Retrieve a pointer to a structure containing information about a specific host Api. @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) @return A pointer to an immutable PaHostApiInfo structure describing a specific host API. If the hostApi parameter is out of range or an error is encountered, the function returns NULL. The returned structure is owned by the PortAudio implementation and must not be manipulated or freed. The pointer is only guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). */ const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi ); /** Convert a static host API unique identifier, into a runtime host API index. @param type A unique host API identifier belonging to the PaHostApiTypeId enumeration. @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. The paHostApiNotFound error code indicates that the host API specified by the type parameter is not available. @see PaHostApiTypeId */ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ); /** Convert a host-API-specific device index to standard PortAudio device index. This function may be used in conjunction with the deviceCount field of PaHostApiInfo to enumerate all devices for the specified host API. @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) @param hostApiDeviceIndex A valid per-host device index in the range 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1) @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1) or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. A paInvalidHostApi error code indicates that the host API index specified by the hostApi parameter is out of range. A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter is out of range. @see PaHostApiInfo */ PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex ); /** Structure used to return information about a host error condition. */ typedef struct PaHostErrorInfo { PaHostApiTypeId hostApiType; /**< the host API which returned the error code */ long errorCode; /**< the error code returned */ const char *errorText; /**< a textual description of the error if available, otherwise a zero-length string */ } PaHostErrorInfo; /** Return information about the last host error encountered. The error information returned by Pa_GetLastHostErrorInfo() will never be modified asyncronously by errors occurring in other PortAudio owned threads (such as the thread that manages the stream callback.) This function is provided as a last resort, primarily to enhance debugging by providing clients with access to all available error information. @return A pointer to an immutable structure constaining information about the host error. The values in this structure will only be valid if a PortAudio function has previously returned the paUnanticipatedHostError error code. */ const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ); /* Device enumeration and capabilities */ /** Retrieve the number of available devices. The number of available devices may be zero. @return A non-negative value indicating the number of available devices or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ PaDeviceIndex Pa_GetDeviceCount( void ); /** Retrieve the index of the default input device. The result can be used in the inputDevice parameter to Pa_OpenStream(). @return The default input device index for the default host API, or paNoDevice if no default input device is available or an error was encountered. */ PaDeviceIndex Pa_GetDefaultInputDevice( void ); /** Retrieve the index of the default output device. The result can be used in the outputDevice parameter to Pa_OpenStream(). @return The default output device index for the defualt host API, or paNoDevice if no default output device is available or an error was encountered. @note On the PC, the user can specify a default device by setting an environment variable. For example, to use device #1.
     set PA_RECOMMENDED_OUTPUT_DEVICE=1
    
The user should first determine the available device ids by using the supplied application "pa_devs". */ PaDeviceIndex Pa_GetDefaultOutputDevice( void ); /** The type used to represent monotonic time in seconds that can be used for syncronisation. The type is used for the outTime argument to the PaStreamCallback and as the result of Pa_GetStreamTime(). @see PaStreamCallback, Pa_GetStreamTime */ typedef double PaTime; /** A type used to specify one or more sample formats. Each value indicates a possible format for sound data passed to and from the stream callback, Pa_ReadStream and Pa_WriteStream. The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8 and aUInt8 are usually implemented by all implementations. The floating point representation (paFloat32) uses +1.0 and -1.0 as the maximum and minimum respectively. paUInt8 is an unsigned 8 bit format where 128 is considered "ground" The paNonInterleaved flag indicates that a multichannel buffer is passed as a set of non-interleaved pointers. @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo @see paFloat32, paInt16, paInt32, paInt24, paInt8 @see paUInt8, paCustomFormat, paNonInterleaved */ typedef unsigned long PaSampleFormat; #define paFloat32 ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */ #define paInt32 ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */ #define paInt24 ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */ #define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */ #define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */ #define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */ #define paCustomFormat ((PaSampleFormat) 0x00010000)/**< @see PaSampleFormat */ #define paNonInterleaved ((PaSampleFormat) 0x80000000) /** A structure providing information and capabilities of PortAudio devices. Devices may support input, output or both input and output. */ typedef struct PaDeviceInfo { int structVersion; /* this is struct version 2 */ const char *name; PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/ int maxInputChannels; int maxOutputChannels; /* Default latency values for interactive performance. */ PaTime defaultLowInputLatency; PaTime defaultLowOutputLatency; /* Default latency values for robust non-interactive applications (eg. playing sound files). */ PaTime defaultHighInputLatency; PaTime defaultHighOutputLatency; double defaultSampleRate; } PaDeviceInfo; /** Retrieve a pointer to a PaDeviceInfo structure containing information about the specified device. @return A pointer to an immutable PaDeviceInfo structure. If the device parameter is out of range the function returns NULL. @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1) @note PortAudio manages the memory referenced by the returned pointer, the client must not manipulate or free the memory. The pointer is only guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). @see PaDeviceInfo, PaDeviceIndex */ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ); /** Parameters for one direction (input or output) of a stream. */ typedef struct PaStreamParameters { /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1) specifying the device to be used or the special constant paUseHostApiSpecificDeviceSpecification which indicates that the actual device(s) to use are specified in hostApiSpecificStreamInfo. This field must not be set to paNoDevice. */ PaDeviceIndex device; /** The number of channels of sound to be delivered to the stream callback or accessed by Pa_ReadStream() or Pa_WriteStream(). It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the device specified by the device parameter. */ int channelCount; /** The sample format of the buffer provided to the stream callback, a_ReadStream() or Pa_WriteStream(). It may be any of the formats described by the PaSampleFormat enumeration. */ PaSampleFormat sampleFormat; /** The desired latency in seconds. Where practical, implementations should configure their latency based on these parameters, otherwise they may choose the closest viable latency instead. Unless the suggested latency is greater than the absolute upper limit for the device implementations should round the suggestedLatency up to the next practial value - ie to provide an equal or higher latency than suggestedLatency wherever possibe. Actual latency values for an open stream may be retrieved using the inputLatency and outputLatency fields of the PaStreamInfo structure returned by Pa_GetStreamInfo(). @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo */ PaTime suggestedLatency; /** An optional pointer to a host api specific data structure containing additional information for device setup and/or stream processing. hostApiSpecificStreamInfo is never required for correct operation, if not used it should be set to NULL. */ void *hostApiSpecificStreamInfo; } PaStreamParameters; /** Return code for Pa_IsFormatSupported indicating success. */ #define paFormatIsSupported (0) /** Determine whether it would be possible to open a stream with the specified parameters. @param inputParameters A structure that describes the input parameters used to open a stream. The suggestedLatency field is ignored. See PaStreamParameters for a description of these parameters. inputParameters must be NULL for output-only streams. @param outputParameters A structure that describes the output parameters used to open a stream. The suggestedLatency field is ignored. See PaStreamParameters for a description of these parameters. outputParameters must be NULL for input-only streams. @param sampleRate The required sampleRate. For full-duplex streams it is the sample rate for both input and output @return Returns 0 if the format is supported, and an error code indicating why the format is not supported otherwise. The constant paFormatIsSupported is provided to compare with the return value for success. @see paFormatIsSupported, PaStreamParameters */ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); /* Streaming types and functions */ /** A single PaStream can provide multiple channels of real-time streaming audio input and output to a client application. A stream provides access to audio hardware represented by one or more PaDevices. Depending on the underlying Host API, it may be possible to open multiple streams using the same device, however this behavior is implementation defined. Portable applications should assume that a PaDevice may be simultaneously used by at most one PaStream. Pointers to PaStream objects are passed between PortAudio functions that operate on streams. @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream, Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive, Pa_GetStreamTime, Pa_GetStreamCpuLoad */ typedef void PaStream; /** Can be passed as the framesPerBuffer parameter to Pa_OpenStream() or Pa_OpenDefaultStream() to indicate that the stream callback will accept buffers of any size. */ #define paFramesPerBufferUnspecified (0) /** Flags used to control the behavior of a stream. They are passed as parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be ORed together. @see Pa_OpenStream, Pa_OpenDefaultStream @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput, paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags */ typedef unsigned long PaStreamFlags; /** @see PaStreamFlags */ #define paNoFlag ((PaStreamFlags) 0) /** Disable default clipping of out of range samples. @see PaStreamFlags */ #define paClipOff ((PaStreamFlags) 0x00000001) /** Disable default dithering. @see PaStreamFlags */ #define paDitherOff ((PaStreamFlags) 0x00000002) /** Flag requests that where possible a full duplex stream will not discard overflowed input samples without calling the stream callback. This flag is only valid for full duplex callback streams and only when used in combination with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using this flag incorrectly results in a paInvalidFlag error being returned from Pa_OpenStream and Pa_OpenDefaultStream. @see PaStreamFlags, paFramesPerBufferUnspecified */ #define paNeverDropInput ((PaStreamFlags) 0x00000004) /** Call the stream callback to fill initial output buffers, rather than the default behavior of priming the buffers with zeros (silence). This flag has no effect for input-only and blocking read/write streams. @see PaStreamFlags */ #define paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008) /** A mask specifying the platform specific bits. @see PaStreamFlags */ #define paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000) /** Timing information for the buffers passed to the stream callback. */ typedef struct PaStreamCallbackTimeInfo { PaTime inputBufferAdcTime; PaTime currentTime; PaTime outputBufferDacTime; } PaStreamCallbackTimeInfo; /** Flag bit constants for the statusFlags to PaStreamCallback. @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow, paPrimingOutput */ typedef unsigned long PaStreamCallbackFlags; /** In a stream opened with paFramesPerBufferUnspecified, indicates that input data is all silence (zeros) because no real data is available. In a stream opened without paFramesPerBufferUnspecified, it indicates that one or more zero samples have been inserted into the input buffer to compensate for an input underflow. @see PaStreamCallbackFlags */ #define paInputUnderflow ((PaStreamCallbackFlags) 0x00000001) /** In a stream opened with paFramesPerBufferUnspecified, indicates that data prior to the first sample of the input buffer was discarded due to an overflow, possibly because the stream callback is using too much CPU time. Otherwise indicates that data prior to one or more samples in the input buffer was discarded. @see PaStreamCallbackFlags */ #define paInputOverflow ((PaStreamCallbackFlags) 0x00000002) /** Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time. @see PaStreamCallbackFlags */ #define paOutputUnderflow ((PaStreamCallbackFlags) 0x00000004) /** Indicates that output data will be discarded because no room is available. @see PaStreamCallbackFlags */ #define paOutputOverflow ((PaStreamCallbackFlags) 0x00000008) /** Some of all of the output data will be used to prime the stream, input data may be zero. @see PaStreamCallbackFlags */ #define paPrimingOutput ((PaStreamCallbackFlags) 0x00000010) /** Allowable return values for the PaStreamCallback. @see PaStreamCallback */ typedef enum PaStreamCallbackResult { paContinue = 0, paComplete = 1, paAbort = 2 } PaStreamCallbackResult; /** Functions of type PaStreamCallback are implemented by PortAudio clients. They consume, process or generate audio in response to requests from an active PortAudio stream. @param input and @param output are arrays of interleaved samples, the format, packing and number of channels used by the buffers are determined by parameters to Pa_OpenStream(). @param frameCount The number of sample frames to be processed by the stream callback. @param timeInfo The time in seconds when the first sample of the input buffer was received at the audio input, the time in seconds when the first sample of the output buffer will begin being played at the audio output, and the time in seconds when the stream callback was called. See also Pa_GetStreamTime() @param statusFlags Flags indicating whether input and/or output buffers have been inserted or will be dropped to overcome underflow or overflow conditions. @param userData The value of a user supplied pointer passed to Pa_OpenStream() intended for storing synthesis data etc. @return The stream callback should return one of the values in the PaStreamCallbackResult enumeration. To ensure that the callback continues to be called, it should return paContinue (0). Either paComplete or paAbort can be returned to finish stream processing, after either of these values is returned the callback will not be called again. If paAbort is returned the stream will finish as soon as possible. If paComplete is returned, the stream will continue until all buffers generated by the callback have been played. This may be useful in applications such as soundfile players where a specific duration of output is required. However, it is not necessary to utilise this mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also be used to stop the stream. The callback must always fill the entire output buffer irrespective of its return value. @see Pa_OpenStream, Pa_OpenDefaultStream @note With the exception of Pa_GetStreamCpuLoad() it is not permissable to call PortAudio API functions from within the stream callback. */ typedef int PaStreamCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ); /** Opens a stream for either input, output or both. @param stream The address of a PaStream pointer which will receive a pointer to the newly opened stream. @param inputParameters A structure that describes the input parameters used by the opened stream. See PaStreamParameters for a description of these parameters. inputParameters must be NULL for output-only streams. @param outputParameters A structure that describes the output parameters used by the opened stream. See PaStreamParameters for a description of these parameters. outputParameters must be NULL for input-only streams. @param sampleRate The desired sampleRate. For full-duplex streams it is the sample rate for both input and output @param framesPerBuffer The number of frames passed to the stream callback function, or the preferred block granularity for a blocking read/write stream. The special value paFramesPerBufferUnspecified (0) may be used to request that the stream callback will recieve an optimal (and possibly varying) number of frames based on host requirements and the requested latency settings. Note: With some host APIs, the use of non-zero framesPerBuffer for a callback stream may introduce an additional layer of buffering which could introduce additional latency. PortAudio guarantees that the additional latency will be kept to the theoretical minimum however, it is strongly recommended that a non-zero framesPerBuffer value only be used when your algorithm requires a fixed number of frames per stream callback. @param streamFlags Flags which modify the behaviour of the streaming process. This parameter may contain a combination of flags ORed together. Some flags may only be relevant to certain buffer formats. @param streamCallback A pointer to a client supplied function that is responsible for processing and filling input and output buffers. If this parameter is NULL the stream will be opened in 'blocking read/write' mode. In blocking mode, the client can receive sample data using Pa_ReadStream and write sample data using Pa_WriteStream, the number of samples that may be read or written without blocking is returned by Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable respectively. @param userData A client supplied pointer which is passed to the stream callback function. It could for example, contain a pointer to instance data necessary for processing the audio buffers. This parameter is ignored if streamCallback is NULL. @return Upon success Pa_OpenStream() returns paNoError and places a pointer to a valid PaStream in the stream argument. The stream is inactive (stopped). If a call to Pa_OpenStream() fails, a non-zero error code is returned (see PaError for possible error codes) and the value of stream is invalid. @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream, Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable */ PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); /** A simplified version of Pa_OpenStream() that opens the default input and/or output devices. @param stream The address of a PaStream pointer which will receive a pointer to the newly opened stream. @param numInputChannels The number of channels of sound that will be supplied to the stream callback or returned by Pa_ReadStream. It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the default input device. If 0 the stream is opened as an output-only stream. @param numOutputChannels The number of channels of sound to be delivered to the stream callback or passed to Pa_WriteStream. It can range from 1 to the value of maxOutputChannels in the PaDeviceInfo record for the default output dvice. If 0 the stream is opened as an output-only stream. @param sampleFormat The sample format of both the input and output buffers provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream. sampleFormat may be any of the formats described by the PaSampleFormat enumeration. @param sampleRate Same as Pa_OpenStream parameter of the same name. @param framesPerBuffer Same as Pa_OpenStream parameter of the same name. @param streamCallback Same as Pa_OpenStream parameter of the same name. @param userData Same as Pa_OpenStream parameter of the same name. @return As for Pa_OpenStream @see Pa_OpenStream, PaStreamCallback */ PaError Pa_OpenDefaultStream( PaStream** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback *streamCallback, void *userData ); /** Closes an audio stream. If the audio stream is active it discards any pending buffers as if Pa_AbortStream() had been called. */ PaError Pa_CloseStream( PaStream *stream ); /** Functions of type PaStreamFinishedCallback are implemented by PortAudio clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback function. Once registered they are called when the stream becomes inactive (ie once a call to Pa_StopStream() will not block). A stream will become inactive after the stream callback returns non-zero, or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio output, if the stream callback returns paComplete, or Pa_StopStream is called, the stream finished callback will not be called until all generated sample data has been played. @param userData The userData parameter supplied to Pa_OpenStream() @see Pa_SetStreamFinishedCallback */ typedef void PaStreamFinishedCallback( void *userData ); /** Register a stream finished callback function which will be called when the stream becomes inactive. See the description of PaStreamFinishedCallback for further details about when the callback will be called. @param stream a pointer to a PaStream that is in the stopped state - if the stream is not stopped, the stream's finished callback will remain unchanged and an error code will be returned. @param streamFinishedCallback a pointer to a function with the same signature as PaStreamFinishedCallback, that will be called when the stream becomes inactive. Passing NULL for this parameter will un-register a previously registered stream finished callback function. @return on success returns paNoError, otherwise an error code indicating the cause of the error. @see PaStreamFinishedCallback */ PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); /** Commences audio processing. */ PaError Pa_StartStream( PaStream *stream ); /** Terminates audio processing. It waits until all pending audio buffers have been played before it returns. */ PaError Pa_StopStream( PaStream *stream ); /** Terminates audio processing immediately without waiting for pending buffers to complete. */ PaError Pa_AbortStream( PaStream *stream ); /** Determine whether the stream is stopped. A stream is considered to be stopped prior to a successful call to Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream. If a stream callback returns a value other than paContinue the stream is NOT considered to be stopped. @return Returns one (1) when the stream is stopped, zero (0) when the stream is running or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive */ PaError Pa_IsStreamStopped( PaStream *stream ); /** Determine whether the stream is active. A stream is active after a successful call to Pa_StartStream(), until it becomes inactive either as a result of a call to Pa_StopStream() or Pa_AbortStream(), or as a result of a return value other than paContinue from the stream callback. In the latter case, the stream is considered inactive after the last buffer has finished playing. @return Returns one (1) when the stream is active (ie playing or recording audio), zero (0) when not playing or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped */ PaError Pa_IsStreamActive( PaStream *stream ); /** A structure containing unchanging information about an open stream. @see Pa_GetStreamInfo */ typedef struct PaStreamInfo { /** this is struct version 1 */ int structVersion; /** The input latency of the stream in seconds. This value provides the most accurate estimate of input latency available to the implementation. It may differ significantly from the suggestedLatency value passed to Pa_OpenStream(). The value of this field will be zero (0.) for output-only streams. @see PaTime */ PaTime inputLatency; /** The output latency of the stream in seconds. This value provides the most accurate estimate of output latency available to the implementation. It may differ significantly from the suggestedLatency value passed to Pa_OpenStream(). The value of this field will be zero (0.) for input-only streams. @see PaTime */ PaTime outputLatency; /** The sample rate of the stream in Hertz (samples per second). In cases where the hardware sample rate is inaccurate and PortAudio is aware of it, the value of this field may be different from the sampleRate parameter passed to Pa_OpenStream(). If information about the actual hardware sample rate is not available, this field will have the same value as the sampleRate parameter passed to Pa_OpenStream(). */ double sampleRate; } PaStreamInfo; /** Retrieve a pointer to a PaStreamInfo structure containing information about the specified stream. @return A pointer to an immutable PaStreamInfo structure. If the stream parameter invalid, or an error is encountered, the function returns NULL. @param stream A pointer to an open stream previously created with Pa_OpenStream. @note PortAudio manages the memory referenced by the returned pointer, the client must not manipulate or free the memory. The pointer is only guaranteed to be valid until the specified stream is closed. @see PaStreamInfo */ const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ); /** Determine the current time for the stream according to the same clock used to generate buffer timestamps. This time may be used for syncronising other events to the audio stream, for example synchronizing audio to MIDI. @return The stream's current time in seconds, or 0 if an error occurred. @see PaTime, PaStreamCallback */ PaTime Pa_GetStreamTime( PaStream *stream ); /** Retrieve CPU usage information for the specified stream. The "CPU Load" is a fraction of total CPU time consumed by a callback stream's audio processing routines including, but not limited to the client supplied stream callback. This function does not work with blocking read/write streams. This function may be called from the stream callback function or the application. @return A floating point value, typically between 0.0 and 1.0, where 1.0 indicates that the stream callback is consuming the maximum number of CPU cycles possible to maintain real-time operation. A value of 0.5 would imply that PortAudio and the stream callback was consuming roughly 50% of the available CPU time. The return value may exceed 1.0. A value of 0.0 will always be returned for a blocking read/write stream, or if an error occurrs. */ double Pa_GetStreamCpuLoad( PaStream* stream ); /** Read samples from an input stream. The function doesn't return until the entire buffer has been filled - this may involve waiting for the operating system to supply the data. @param stream A pointer to an open stream previously created with Pa_OpenStream. @param buffer A pointer to a buffer of sample frames. The buffer contains samples in the format specified by the inputParameters->sampleFormat field used to open the stream, and the number of channels specified by inputParameters->numChannels. If non-interleaved samples were requested, buffer is a pointer to the first element of an array of non-interleaved buffer pointers, one for each channel. @param frames The number of frames to be read into buffer. This parameter is not constrained to a specific range, however high performance applications will want to match this parameter to the framesPerBuffer parameter used when opening the stream. @return On success PaNoError will be returned, or PaInputOverflowed if input data was discarded by PortAudio after the previous call and before this call. */ PaError Pa_ReadStream( PaStream* stream, void *buffer, unsigned long frames ); /** Write samples to an output stream. This function doesn't return until the entire buffer has been consumed - this may involve waiting for the operating system to consume the data. @param stream A pointer to an open stream previously created with Pa_OpenStream. @param buffer A pointer to a buffer of sample frames. The buffer contains samples in the format specified by the outputParameters->sampleFormat field used to open the stream, and the number of channels specified by outputParameters->numChannels. If non-interleaved samples were requested, buffer is a pointer to the first element of an array of non-interleaved buffer pointers, one for each channel. @param frames The number of frames to be written from buffer. This parameter is not constrained to a specific range, however high performance applications will want to match this parameter to the framesPerBuffer parameter used when opening the stream. @return On success PaNoError will be returned, or paOutputUnderflowed if additional output data was inserted after the previous call and before this call. */ PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); /** Retrieve the number of frames that can be read from the stream without waiting. @return Returns a non-negative value representing the maximum number of frames that can be read from the stream without blocking or busy waiting or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ signed long Pa_GetStreamReadAvailable( PaStream* stream ); /** Retrieve the number of frames that can be written to the stream without waiting. @return Returns a non-negative value representing the maximum number of frames that can be written to the stream without blocking or busy waiting or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ signed long Pa_GetStreamWriteAvailable( PaStream* stream ); /* Miscellaneous utilities */ /** Retrieve the size of a given sample format in bytes. @return The size in bytes of a single sample in the specified format, or paSampleFormatNotSupported if the format is not supported. */ PaError Pa_GetSampleSize( PaSampleFormat format ); /** Put the caller to sleep for at least 'msec' milliseconds. This function is provided only as a convenience for authors of portable code (such as the tests and examples in the PortAudio distribution.) The function may sleep longer than requested so don't rely on this for accurate musical timing. */ void Pa_Sleep( long msec ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PORTAUDIO_H */ 1.9.12~dfsg/windows/portaudio/JackPortAudioDriver.cpp0000644000000000000000000004443313214314510021427 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackDriverLoader.h" #include "driver_interface.h" #include "JackPortAudioDriver.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackError.h" #include "JackTime.h" #include "JackTools.h" #include "JackCompilerDeps.h" #include #include using namespace std; namespace Jack { int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData) { return static_cast(userData)->Render(inputBuffer, outputBuffer, statusFlags); } int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, PaStreamCallbackFlags statusFlags) { fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; if (statusFlags) { if (statusFlags & paOutputUnderflow) jack_error("JackPortAudioDriver::Render paOutputUnderflow"); if (statusFlags & paInputUnderflow) jack_error("JackPortAudioDriver::Render paInputUnderflow"); if (statusFlags & paOutputOverflow) jack_error("JackPortAudioDriver::Render paOutputOverflow"); if (statusFlags & paInputOverflow) jack_error("JackPortAudioDriver::Render paInputOverflow"); if (statusFlags & paPrimingOutput) jack_error("JackPortAudioDriver::Render paOutputUnderflow"); if (statusFlags != paPrimingOutput) { jack_time_t cur_time = GetMicroSeconds(); NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... } } // Setup threaded based log function set_threaded_log_function(); CycleTakeBeginTime(); return (Process() == 0) ? paContinue : paAbort; } int JackPortAudioDriver::Read() { for (int i = 0; i < fCaptureChannels; i++) { memcpy(GetInputBuffer(i), fInputBuffer[i], sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } return 0; } int JackPortAudioDriver::Write() { for (int i = 0; i < fPlaybackChannels; i++) { memcpy(fOutputBuffer[i], GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } return 0; } PaError JackPortAudioDriver::OpenStream(jack_nframes_t buffer_size) { PaStreamParameters inputParameters; PaStreamParameters outputParameters; jack_log("JackPortAudioDriver::OpenStream buffer_size = %d", buffer_size); // Update parameters inputParameters.device = fInputDevice; inputParameters.channelCount = fCaptureChannels; inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point input inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO ? ((fPaDevices->GetHostFromDevice(fInputDevice) == "ASIO") ? 0 : Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency) : 0; inputParameters.hostApiSpecificStreamInfo = NULL; outputParameters.device = fOutputDevice; outputParameters.channelCount = fPlaybackChannels; outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO ? ((fPaDevices->GetHostFromDevice(fOutputDevice) == "ASIO") ? 0 : Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency) : 0; outputParameters.hostApiSpecificStreamInfo = NULL; return Pa_OpenStream(&fStream, (fInputDevice == paNoDevice) ? 0 : &inputParameters, (fOutputDevice == paNoDevice) ? 0 : &outputParameters, fEngineControl->fSampleRate, buffer_size, paNoFlag, // Clipping is on... Render, this); } void JackPortAudioDriver::UpdateLatencies() { jack_latency_range_t input_range; jack_latency_range_t output_range; jack_latency_range_t monitor_range; const PaStreamInfo* info = Pa_GetStreamInfo(fStream); assert(info); for (int i = 0; i < fCaptureChannels; i++) { input_range.max = input_range.min = fEngineControl->fBufferSize + (info->inputLatency * fEngineControl->fSampleRate) + fCaptureLatency; fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); } for (int i = 0; i < fPlaybackChannels; i++) { output_range.max = output_range.min = (info->outputLatency * fEngineControl->fSampleRate) + fPlaybackLatency; if (fEngineControl->fSyncMode) { output_range.max = output_range.min += fEngineControl->fBufferSize; } else { output_range.max = output_range.min += fEngineControl->fBufferSize * 2; } fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); if (fWithMonitorPorts) { monitor_range.min = monitor_range.max = fEngineControl->fBufferSize; fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range); } } } int JackPortAudioDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_uid, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { int in_max = 0; int out_max = 0; PaError err = paNoError; if (!fPaDevices) { fPaDevices = new PortAudioDevices(); } fCaptureLatency = capture_latency; fPlaybackLatency = playback_latency; jack_log("JackPortAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s samplerate = %ld", buffer_size, inchannels, outchannels, capture_driver_uid, playback_driver_uid, samplerate); // Get devices if (capturing) { if (fPaDevices->GetInputDeviceFromName(capture_driver_uid, fInputDevice, in_max) < 0) { goto error; } } if (playing) { if (fPaDevices->GetOutputDeviceFromName(playback_driver_uid, fOutputDevice, out_max) < 0) { goto error; } } // If ASIO, request for preferred size (assuming fInputDevice and fOutputDevice are the same) if (buffer_size == 0) { buffer_size = fPaDevices->GetPreferredBufferSize(fInputDevice); jack_log("JackPortAudioDriver::Open preferred buffer_size = %d", buffer_size); } // Generic JackAudioDriver Open char capture_driver_name[JACK_CLIENT_NAME_SIZE]; char playback_driver_name[JACK_CLIENT_NAME_SIZE]; snprintf(capture_driver_name, sizeof(capture_driver_name), "%s", capture_driver_uid); snprintf(playback_driver_name, sizeof(playback_driver_name), "%s", playback_driver_uid); if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) { return -1; } jack_log("JackPortAudioDriver::Open fInputDevice = %d, fOutputDevice %d", fInputDevice, fOutputDevice); // Default channels number required if (inchannels == 0) { jack_log("JackPortAudioDriver::Open setup max in channels = %ld", in_max); inchannels = in_max; } if (outchannels == 0) { jack_log("JackPortAudioDriver::Open setup max out channels = %ld", out_max); outchannels = out_max; } // Too many channels required, take max available if (inchannels > in_max) { jack_error("This device has only %d available input channels.", in_max); inchannels = in_max; } if (outchannels > out_max) { jack_error("This device has only %d available output channels.", out_max); outchannels = out_max; } // Core driver may have changed the in/out values fCaptureChannels = inchannels; fPlaybackChannels = outchannels; err = OpenStream(buffer_size); if (err != paNoError) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); goto error; } #ifdef __APPLE__ fEngineControl->fPeriod = fEngineControl->fPeriodUsecs * 1000; fEngineControl->fComputation = JackTools::ComputationMicroSec(fEngineControl->fBufferSize) * 1000; fEngineControl->fConstraint = fEngineControl->fPeriodUsecs * 1000; #endif return 0; error: JackAudioDriver::Close(); jack_error("Can't open default PortAudio device"); return -1; } int JackPortAudioDriver::Close() { // Generic audio driver close jack_log("JackPortAudioDriver::Close"); JackAudioDriver::Close(); PaError err = Pa_CloseStream(fStream); if (err != paNoError) { jack_error("Pa_CloseStream error = %s", Pa_GetErrorText(err)); } delete fPaDevices; fPaDevices = NULL; return (err != paNoError) ? -1 : 0; } int JackPortAudioDriver::Attach() { if (JackAudioDriver::Attach() == 0) { const char* alias; #if defined(HAVE_ASIO) if (fInputDevice != paNoDevice && fPaDevices->GetHostFromDevice(fInputDevice) == "ASIO") { for (int i = 0; i < fCaptureChannels; i++) { if (PaAsio_GetInputChannelName(fInputDevice, i, &alias) == paNoError) { JackPort* port = fGraphManager->GetPort(fCapturePortList[i]); port->SetAlias(alias); } } } if (fOutputDevice != paNoDevice && fPaDevices->GetHostFromDevice(fOutputDevice) == "ASIO") { for (int i = 0; i < fPlaybackChannels; i++) { if (PaAsio_GetOutputChannelName(fOutputDevice, i, &alias) == paNoError) { JackPort* port = fGraphManager->GetPort(fPlaybackPortList[i]); port->SetAlias(alias); } } } #endif return 0; } else { return -1; } } int JackPortAudioDriver::Start() { jack_log("JackPortAudioDriver::Start"); if (JackAudioDriver::Start() == 0) { PaError err; if ((err = Pa_StartStream(fStream)) == paNoError) { return 0; } jack_error("Pa_StartStream error = %s", Pa_GetErrorText(err)); JackAudioDriver::Stop(); } return -1; } int JackPortAudioDriver::Stop() { jack_log("JackPortAudioDriver::Stop"); PaError err; if ((err = Pa_StopStream(fStream)) != paNoError) { jack_error("Pa_StopStream error = %s", Pa_GetErrorText(err)); } if (JackAudioDriver::Stop() < 0) { return -1; } else { return (err == paNoError) ? 0 : -1; } } int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size) { PaError err; if (fStream && (err = Pa_CloseStream(fStream)) != paNoError) { jack_error("Pa_CloseStream error = %s", Pa_GetErrorText(err)); goto error; } // It seems that some ASIO drivers (like ASIO4All) needs this to restart correctly; delete fPaDevices; fPaDevices = new PortAudioDevices(); err = OpenStream(buffer_size); if (err != paNoError) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); goto error; } else { JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails return 0; } error: fStream = NULL; return -1; } } // end of namespace #ifdef __cplusplus extern "C" { #endif #include "JackCompilerDeps.h" SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("portaudio", JackDriverMaster, "PortAudio API based audio backend", &filler); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "channels", 'c', JackDriverParamUInt, &value, NULL, "Maximum number of channels", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Maximum number of input channels", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Maximum number of output channels", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set PortAudio device name", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Provide playback ports. Optionally set PortAudio device name", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "monitor", 'm', JackDriverParamBool, &value, NULL, "Provide monitor ports for the output", NULL); value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports", NULL); value.ui = 44100U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = 512U; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", "Frames per period. If 0 and ASIO driver, will take preferred value"); jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "PortAudio device name", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency", NULL); value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "list-devices", 'l', JackDriverParamBool, &value, NULL, "Display available PortAudio devices", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t srate = 44100; jack_nframes_t frames_per_interrupt = 512; const char* capture_pcm_name = ""; const char* playback_pcm_name = ""; bool capture = false; bool playback = false; int chan_in = 0; int chan_out = 0; bool monitor = false; const JSList *node; const jack_driver_param_t *param; jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; PortAudioDevices* pa_devices = new PortAudioDevices(); for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'd': capture_pcm_name = param->value.str; playback_pcm_name = param->value.str; break; case 'D': capture = true; playback = true; break; case 'c': chan_in = chan_out = (int)param->value.ui; break; case 'i': chan_in = (int)param->value.ui; break; case 'o': chan_out = (int)param->value.ui; break; case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { capture_pcm_name = param->value.str; } break; case 'P': playback = true; if (strcmp(param->value.str, "none") != 0) { playback_pcm_name = param->value.str; } break; case 'm': monitor = param->value.i; break; case 'r': srate = param->value.ui; break; case 'p': frames_per_interrupt = (unsigned int)param->value.ui; break; case 'I': systemic_input_latency = param->value.ui; break; case 'O': systemic_output_latency = param->value.ui; break; case 'l': pa_devices->DisplayDevicesNames(); // Stops the server in this case return NULL; } } // duplex is the default if (!capture && !playback) { capture = true; playback = true; } Jack::JackDriverClientInterface* driver = new Jack::JackPortAudioDriver("system", "portaudio", engine, table, pa_devices); if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency) == 0) { return driver; } else { delete driver; return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/windows/portaudio/JackPortAudioDevices.h0000644000000000000000000000427113214314510021217 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __PortAudioDevices__ #define __PortAudioDevices__ #include #include #include "portaudio.h" #include "pa_asio.h" /*! \brief A PortAudio Devices manager. */ class PortAudioDevices { private: PaHostApiIndex fNumHostApi; //number of hosts PaDeviceIndex fNumDevice; //number of devices PaDeviceInfo** fDeviceInfo; //array of device info std::string* fHostName; //array of host names (matched with host id's) public: PortAudioDevices(); ~PortAudioDevices(); PaDeviceIndex GetNumDevice(); PaDeviceInfo* GetDeviceInfo(PaDeviceIndex id); std::string GetDeviceName(PaDeviceIndex id); std::string GetHostFromDevice(PaDeviceInfo* device); std::string GetHostFromDevice(PaDeviceIndex id); std::string GetFullName(PaDeviceIndex id); std::string GetFullName(std::string hostname, std::string devicename); PaDeviceInfo* GetDeviceFromFullName(std::string fullname, PaDeviceIndex& id, bool isInput); void PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters); int GetInputDeviceFromName(const char* name, PaDeviceIndex& device, int& in_max); int GetOutputDeviceFromName(const char* name, PaDeviceIndex& device, int& out_max); int GetPreferredBufferSize(PaDeviceIndex id); void DisplayDevicesNames(); bool IsDuplex(PaDeviceIndex id); }; #endif 1.9.12~dfsg/windows/portaudio/JackPortAudioDriver.h0000644000000000000000000000565413214314510021076 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackPortAudioDriver__ #define __JackPortAudioDriver__ #include "JackAudioDriver.h" #include "JackPortAudioDevices.h" #include "JackMMCSS.h" namespace Jack { /*! \brief The PortAudio driver. */ class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver { private: PaStream* fStream; jack_default_audio_sample_t** fInputBuffer; jack_default_audio_sample_t** fOutputBuffer; PaDeviceIndex fInputDevice; PaDeviceIndex fOutputDevice; PortAudioDevices* fPaDevices; static int Render(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData); PaError OpenStream(jack_nframes_t buffer_size); void UpdateLatencies(); int Render(const void* inputBuffer, void* outputBuffer, PaStreamCallbackFlags statusFlags); public: JackPortAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, PortAudioDevices* pa_devices) : JackMMCSS(), JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL), fInputDevice(paNoDevice), fOutputDevice(paNoDevice), fPaDevices(pa_devices) {} virtual ~JackPortAudioDriver() { delete fPaDevices; } int Open(jack_nframes_t buffe_size, jack_nframes_t samplerate, bool capturing, bool playing, int chan_in, int chan_out, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); int Close(); int Attach(); int Start(); int Stop(); int Read(); int Write(); // BufferSize can be changed bool IsFixedBufferSize() { return false; } int SetBufferSize(jack_nframes_t buffer_size); }; } // end of namespace #endif 1.9.12~dfsg/windows/portaudio/JackPortAudioAdapter.cpp0000644000000000000000000002401213214314510021543 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackPortAudioAdapter.h" #include "JackError.h" namespace Jack { int JackPortAudioAdapter::Render(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData) { static_cast(userData)->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, framesPerBuffer); return paContinue; } JackPortAudioAdapter::JackPortAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) : JackAudioAdapterInterface(buffer_size, sample_rate) { jack_log("JackPortAudioAdapter::JackPortAudioAdapter buffer_size = %d, sample_rate = %d", buffer_size, sample_rate); const JSList* node; const jack_driver_param_t* param; int in_max = 0; int out_max = 0; fInputDevice = Pa_GetDefaultInputDevice(); fOutputDevice = Pa_GetDefaultOutputDevice(); for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'i' : fCaptureChannels = param->value.ui; break; case 'o' : fPlaybackChannels = param->value.ui; break; case 'C' : if (fPaDevices.GetInputDeviceFromName(param->value.str, fInputDevice, in_max) < 0) { jack_error("Can't use %s, taking default input device", param->value.str); fInputDevice = Pa_GetDefaultInputDevice(); } break; case 'P' : if (fPaDevices.GetOutputDeviceFromName(param->value.str, fOutputDevice, out_max) < 0) { jack_error("Can't use %s, taking default output device", param->value.str); fOutputDevice = Pa_GetDefaultOutputDevice(); } break; case 'r' : SetAdaptedSampleRate(param->value.ui); break; case 'p' : SetAdaptedBufferSize(param->value.ui); break; case 'd' : if (fPaDevices.GetInputDeviceFromName(param->value.str, fInputDevice, in_max) < 0) jack_error("Can't use %s, taking default input device", param->value.str); if (fPaDevices.GetOutputDeviceFromName(param->value.str, fOutputDevice, out_max) < 0) jack_error("Can't use %s, taking default output device", param->value.str); break; case 'l' : fPaDevices.DisplayDevicesNames(); break; case 'q': fQuality = param->value.ui; break; case 'g': fRingbufferCurSize = param->value.ui; fAdaptative = false; break; } } //max channels if (in_max == 0 && fInputDevice != paNoDevice) in_max = fPaDevices.GetDeviceInfo(fInputDevice)->maxInputChannels; if (out_max == 0 && fOutputDevice != paNoDevice) out_max = fPaDevices.GetDeviceInfo(fOutputDevice)->maxOutputChannels; //effective channels if ((fCaptureChannels == 0) || (fCaptureChannels > in_max)) fCaptureChannels = in_max; if ((fPlaybackChannels == 0) || (fPlaybackChannels > out_max)) fPlaybackChannels = out_max; //set adapter interface channels SetInputs(fCaptureChannels); SetOutputs(fPlaybackChannels); } int JackPortAudioAdapter::Open() { PaError err; PaStreamParameters inputParameters; PaStreamParameters outputParameters; if (fInputDevice == paNoDevice && fOutputDevice == paNoDevice) { jack_error("No input and output device!!"); return -1; } jack_log("JackPortAudioAdapter::Open fInputDevice = %d DeviceName %s", fInputDevice, fPaDevices.GetFullName(fInputDevice).c_str()); jack_log("JackPortAudioAdapter::Open fOutputDevice = %d DeviceName %s", fOutputDevice, fPaDevices.GetFullName(fOutputDevice).c_str()); jack_log("JackPortAudioAdapter::Open fAdaptedBufferSize = %u fAdaptedSampleRate %u", fAdaptedBufferSize, fAdaptedSampleRate); inputParameters.device = fInputDevice; inputParameters.channelCount = fCaptureChannels; inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO ? fPaDevices.GetDeviceInfo(fInputDevice)->defaultLowInputLatency : 0; inputParameters.hostApiSpecificStreamInfo = NULL; outputParameters.device = fOutputDevice; outputParameters.channelCount = fPlaybackChannels; outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO ? fPaDevices.GetDeviceInfo(fOutputDevice)->defaultLowOutputLatency : 0; outputParameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream( &fStream, (fInputDevice == paNoDevice) ? 0 : &inputParameters, (fOutputDevice == paNoDevice) ? 0 : &outputParameters, fAdaptedSampleRate, fAdaptedBufferSize, paNoFlag, // Clipping is on... Render, this); if (err != paNoError) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); return -1; } err = Pa_StartStream(fStream); if (err != paNoError) { jack_error("Pa_StartStream error = %s", Pa_GetErrorText(err)); return -1; } jack_log("JackPortAudioAdapter::Open OK"); return 0; } int JackPortAudioAdapter::Close() { #ifdef JACK_MONITOR fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif jack_log("JackPortAudioAdapter::Close"); Pa_StopStream(fStream); jack_log("JackPortAudioAdapter:: Pa_StopStream"); Pa_CloseStream(fStream); jack_log("JackPortAudioAdapter:: Pa_CloseStream"); return 0; } int JackPortAudioAdapter::SetSampleRate(jack_nframes_t sample_rate) { JackAudioAdapterInterface::SetHostSampleRate(sample_rate); Close(); return Open(); } int JackPortAudioAdapter::SetBufferSize(jack_nframes_t buffer_size) { JackAudioAdapterInterface::SetHostBufferSize(buffer_size); Close(); return Open(); } } // namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set PortAudio device name", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Provide playback ports. Optionally set PortAudio device name", NULL); value.ui = 44100U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = 512U; jack_driver_descriptor_add_parameter(desc, &filler, "periodsize", 'p', JackDriverParamUInt, &value, NULL, "Period size", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "PortAudio device name", NULL); value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "list-devices", 'l', JackDriverParamBool, &value, NULL, "Display available PortAudio devices", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL); value.ui = 32768; jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)"); return desc; } #ifdef __cplusplus } #endif 1.9.12~dfsg/windows/portaudio/pa_asio.h0000644000000000000000000001316513214314510016632 0ustar rootroot#ifndef PA_ASIO_H #define PA_ASIO_H /* * $Id: pa_asio.h 1667 2011-05-02 15:49:20Z rossb $ * PortAudio Portable Real-Time Audio Library * ASIO specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief ASIO-specific PortAudio API extension header file. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** Retrieve legal native buffer sizes for the specificed device, in sample frames. @param device The global index of the device about which the query is being made. @param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value. @param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value. @param preferredBufferSizeFrames A pointer to the location which will receive the preferred buffer size value. @param granularity A pointer to the location which will receive the "granularity". This value determines the step size used to compute the legal values between minBufferSizeFrames and maxBufferSizeFrames. If granularity is -1 then available buffer size values are powers of two. @see ASIOGetBufferSize in the ASIO SDK. @note: this function used to be called PaAsio_GetAvailableLatencyValues. There is a #define that maps PaAsio_GetAvailableLatencyValues to this function for backwards compatibility. */ PaError PaAsio_GetAvailableBufferSizes( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames, long *preferredBufferSizeFrames, long *granularity ); /** Backwards compatibility alias for PaAsio_GetAvailableBufferSizes @see PaAsio_GetAvailableBufferSizes */ #define PaAsio_GetAvailableLatencyValues PaAsio_GetAvailableBufferSizes /** Display the ASIO control panel for the specified device. @param device The global index of the device whose control panel is to be displayed. @param systemSpecific On Windows, the calling application's main window handle, on Macintosh this value should be zero. */ PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific ); /** Retrieve a pointer to a string containing the name of the specified input channel. The string is valid until Pa_Terminate is called. The string will be no longer than 32 characters including the null terminator. */ PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ); /** Retrieve a pointer to a string containing the name of the specified input channel. The string is valid until Pa_Terminate is called. The string will be no longer than 32 characters including the null terminator. */ PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ); /** Set the sample rate of an open paASIO stream. @param stream The stream to operate on. @param sampleRate The new sample rate. Note that this function may fail if the stream is alredy running and the ASIO driver does not support switching the sample rate of a running stream. Returns paIncompatibleStreamHostApi if stream is not a paASIO stream. */ PaError PaAsio_SetStreamSampleRate( PaStream* stream, double sampleRate ); #define paAsioUseChannelSelectors (0x01) typedef struct PaAsioStreamInfo{ unsigned long size; /**< sizeof(PaAsioStreamInfo) */ PaHostApiTypeId hostApiType; /**< paASIO */ unsigned long version; /**< 1 */ unsigned long flags; /* Support for opening only specific channels of an ASIO device. If the paAsioUseChannelSelectors flag is set, channelSelectors is a pointer to an array of integers specifying the device channels to use. When used, the length of the channelSelectors array must match the corresponding channelCount parameter to Pa_OpenStream() otherwise a crash may result. The values in the selectors array must specify channels within the range of supported channels for the device or paInvalidChannelCount will result. */ int *channelSelectors; }PaAsioStreamInfo; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ASIO_H */ 1.9.12~dfsg/windows/portaudio/JackPortAudioAdapter.h0000644000000000000000000000370013214314510021211 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackPortAudioAdapter__ #define __JackPortAudioAdapter__ #include "JackAudioAdapter.h" #include "JackPortAudioDevices.h" #include "jslist.h" namespace Jack { /*! \brief Audio adapter using PortAudio API. */ class JackPortAudioAdapter : public JackAudioAdapterInterface { private: PortAudioDevices fPaDevices; PaStream* fStream; PaDeviceIndex fInputDevice; PaDeviceIndex fOutputDevice; static int Render(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData); public: JackPortAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackPortAudioAdapter() {} int Open(); int Close(); int SetSampleRate(jack_nframes_t sample_rate); int SetBufferSize(jack_nframes_t buffer_size); }; } #ifdef __cplusplus extern "C" { #endif #include "JackCompilerDeps.h" #include "driver_interface.h" SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor(); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/windows/portaudio/JackPortAudioDevices.cpp0000644000000000000000000002553713214314510021562 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackPortAudioDevices.h" #include "JackError.h" #include using namespace std; PortAudioDevices::PortAudioDevices() { PaError err; PaDeviceIndex id; jack_log("Initializing PortAudio..."); if ((err = Pa_Initialize()) == paNoError) { fNumHostApi = Pa_GetHostApiCount(); fNumDevice = Pa_GetDeviceCount(); fDeviceInfo = new PaDeviceInfo*[fNumDevice]; for (id = 0; id < fNumDevice; id++) { fDeviceInfo[id] = const_cast(Pa_GetDeviceInfo(id)); } fHostName = new string[fNumHostApi]; for (id = 0; id < fNumHostApi; id++) { fHostName[id] = string(Pa_GetHostApiInfo(id)->name); } } else { jack_error("JackPortAudioDriver::Pa_Initialize error = %s", Pa_GetErrorText(err)); } } PortAudioDevices::~PortAudioDevices() { jack_log("Terminate PortAudio..."); Pa_Terminate(); delete[] fDeviceInfo; delete[] fHostName; } PaDeviceIndex PortAudioDevices::GetNumDevice() { return fNumDevice; } PaDeviceInfo* PortAudioDevices::GetDeviceInfo(PaDeviceIndex id) { return fDeviceInfo[id]; } string PortAudioDevices::GetDeviceName(PaDeviceIndex id) { return string(fDeviceInfo[id]->name); } string PortAudioDevices::GetHostFromDevice(PaDeviceInfo* device) { return fHostName[device->hostApi]; } string PortAudioDevices::GetHostFromDevice(PaDeviceIndex id) { return fHostName[fDeviceInfo[id]->hostApi]; } string PortAudioDevices::GetFullName(PaDeviceIndex id) { string hostname = GetHostFromDevice(id); string devicename = GetDeviceName(id); //some hostname are quite long...use shortcuts if (hostname.compare("Windows DirectSound") == 0) { hostname = string("DirectSound"); } return (hostname + "::" + devicename); } string PortAudioDevices::GetFullName(std::string hostname, std::string devicename) { //some hostname are quite long...use shortcuts if (hostname.compare("Windows DirectSound") == 0) { hostname = string("DirectSound"); } return (hostname + "::" + devicename); } PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName(string fullname, PaDeviceIndex& id, bool isInput) { PaDeviceInfo* ret = NULL; //no driver to find if (fullname.size() == 0) { return NULL; } //first get host and device names from fullname string::size_type separator = fullname.find("::", 0); if (separator == string::npos) { return NULL; } char* hostname = (char*)malloc(separator + 9); fill_n(hostname, separator + 9, 0); fullname.copy(hostname, separator); //we need the entire hostname, replace shortcuts if (strcmp(hostname, "DirectSound") == 0) { strcpy(hostname, "Windows DirectSound"); } string devicename = fullname.substr(separator + 2); //then find the corresponding device for (PaDeviceIndex dev_id = 0; dev_id < fNumDevice; dev_id++) { bool flag = (isInput) ? (fDeviceInfo[dev_id]->maxInputChannels > 0) : (fDeviceInfo[dev_id]->maxOutputChannels > 0); if ((GetHostFromDevice(dev_id).compare(hostname) == 0) && (GetDeviceName(dev_id).compare(devicename) == 0) && flag) { id = dev_id; ret = fDeviceInfo[dev_id]; } } free(hostname); return ret; } void PortAudioDevices::PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters) { static double standardSampleRates[] = { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0, 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1 /* negative terminated list */ }; int i, printCount; PaError err; printCount = 0; for (i = 0; standardSampleRates[i] > 0; i++) { err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]); if (err == paFormatIsSupported) { if (printCount == 0) { jack_info("\t%8.2f", standardSampleRates[i]); printCount = 1; } else if (printCount == 4) { jack_info(",\n\t%8.2f", standardSampleRates[i]); printCount = 1; } else { jack_info(", %8.2f", standardSampleRates[i]); ++printCount; } } } if (!printCount) { jack_info("None"); } else { jack_info("\n"); } } int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_input) { string fullname = string(devicename); PaDeviceInfo* device = GetDeviceFromFullName(fullname, id, true); if (device) { max_input = device->maxInputChannels; } else { id = Pa_GetDefaultInputDevice(); if (fullname.size()) { jack_error("Can't open %s, PortAudio will use default input device.", devicename); } if (id == paNoDevice) { return -1; } max_input = GetDeviceInfo(id)->maxInputChannels; } return id; } int PortAudioDevices::GetOutputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_output) { string fullname = string(devicename); PaDeviceInfo* device = GetDeviceFromFullName(fullname, id, false); if (device) { max_output = device->maxOutputChannels; } else { id = Pa_GetDefaultOutputDevice(); if (fullname.size()) { jack_error("Can't open %s, PortAudio will use default output device.", devicename); } if (id == paNoDevice) { return -1; } max_output = GetDeviceInfo(id)->maxOutputChannels; } return id; } int PortAudioDevices::GetPreferredBufferSize(PaDeviceIndex id) { #if defined(WIN32) && defined(HAVE_ASIO) /* ASIO specific latency information */ if (Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO) { long minLatency, maxLatency, preferredLatency, granularity; PaAsio_GetAvailableBufferSizes(id, &minLatency, &maxLatency, &preferredLatency, &granularity); jack_info("ASIO minimum buffer size = %ld", minLatency); jack_info("ASIO maximum buffer size = %ld", maxLatency); jack_info("ASIO preferred buffer size = %ld", preferredLatency); if (granularity == -1) { jack_info("ASIO buffer granularity = power of 2"); } else { jack_info("ASIO buffer granularity = %ld", granularity); } return preferredLatency; } else #endif { return 512; // Non ASIO driver, returns generic value } } void PortAudioDevices::DisplayDevicesNames() { PaDeviceIndex id; PaStreamParameters inputParameters, outputParameters; jack_info("********************** Devices list, %d detected **********************", fNumDevice); for (id = 0; id < fNumDevice; id++) { jack_info("-------- device #%d ------------------------------------------------", id); if (id == Pa_GetDefaultInputDevice()) { jack_info("[ Default Input ]"); } else if (id == Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->defaultInputDevice) { const PaHostApiInfo *host_info = Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi); jack_info("[ Default %s Input ]", host_info->name); } if (id == Pa_GetDefaultOutputDevice()) { jack_info("[ Default Output ]"); } else if (id == Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->defaultOutputDevice) { const PaHostApiInfo *host_info = Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi); jack_info("[ Default %s Output ]", host_info->name); } /* print device info fields */ jack_info("Name = %s", GetFullName(id).c_str()); jack_info("Max inputs = %d", fDeviceInfo[id]->maxInputChannels); jack_info("Max outputs = %d", fDeviceInfo[id]->maxOutputChannels); #if defined(WIN32) && defined(HAVE_ASIO) /* ASIO specific latency information */ if (Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO) { long minLatency, maxLatency, preferredLatency, granularity; PaAsio_GetAvailableBufferSizes(id, &minLatency, &maxLatency, &preferredLatency, &granularity); jack_info("ASIO minimum buffer size = %ld", minLatency); jack_info("ASIO maximum buffer size = %ld", maxLatency); jack_info("ASIO preferred buffer size = %ld", preferredLatency); if (granularity == -1) { jack_info("ASIO buffer granularity = power of 2"); } else { jack_info("ASIO buffer granularity = %ld", granularity); } } #endif jack_info("Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate); /* poll for standard sample rates */ inputParameters.device = id; inputParameters.channelCount = fDeviceInfo[id]->maxInputChannels; inputParameters.sampleFormat = paInt16; inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ inputParameters.hostApiSpecificStreamInfo = NULL; outputParameters.device = id; outputParameters.channelCount = fDeviceInfo[id]->maxOutputChannels; outputParameters.sampleFormat = paInt16; outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ outputParameters.hostApiSpecificStreamInfo = NULL; } jack_info("**************************** End of list ****************************"); } bool PortAudioDevices::IsDuplex(PaDeviceIndex id) { //does the device has in and out facilities if (fDeviceInfo[id]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels) { return true; } //else is another complementary device ? (search in devices with the same name) for (PaDeviceIndex i = 0; i < fNumDevice; i++) { if ((i != id) && (GetDeviceName(i) == GetDeviceName(id))) { if ((fDeviceInfo[i]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels) || (fDeviceInfo[i]->maxOutputChannels && fDeviceInfo[id]->maxInputChannels)) { return true; } } } //then the device isn't full duplex return false; } 1.9.12~dfsg/windows/jack_netsource.cbp0000644000000000000000000001350013214314510016516 0ustar rootroot 1.9.12~dfsg/windows/JackWinThread.cpp0000644000000000000000000001652513214314510016225 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackWinThread.h" #include "JackError.h" #include "JackTime.h" #include #include namespace Jack { DWORD WINAPI JackWinThread::ThreadHandler(void* arg) { JackWinThread* obj = (JackWinThread*)arg; JackRunnableInterface* runnable = obj->fRunnable; // Signal creation thread when started with StartSync jack_log("JackWinThread::ThreadHandler : start"); obj->fStatus = kIniting; // Call Init method if (!runnable->Init()) { jack_error("Thread init fails: thread quits"); return 0; } obj->fStatus = kRunning; // If Init succeed, start the thread loop bool res = true; while (obj->fStatus == kRunning && res) { res = runnable->Execute(); } SetEvent(obj->fEvent); jack_log("JackWinThread::ThreadHandler : exit"); return 0; } JackWinThread::JackWinThread(JackRunnableInterface* runnable) : JackMMCSS(), JackThreadInterface(runnable, 0, false, 0) { fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); fThread = (HANDLE)NULL; assert(fEvent); } JackWinThread::~JackWinThread() { CloseHandle(fEvent); CloseHandle(fThread); } int JackWinThread::Start() { fStatus = kStarting; // Check if the thread was correctly started if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; } else { return 0; } } int JackWinThread::StartSync() { fStatus = kStarting; if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; } else { int count = 0; while (fStatus == kStarting && ++count < 1000) { JackSleep(1000); } return (count == 1000) ? -1 : 0; } } int JackWinThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg) { DWORD id; *thread = CreateThread(NULL, 0, start_routine, arg, 0, &id); if (*thread == NULL) { jack_error("Cannot create thread error = %d", GetLastError()); return -1; } if (realtime) { jack_log("JackWinThread::StartImp : create RT thread"); if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) { jack_error("Cannot set priority class = %d", GetLastError()); return -1; } } else { jack_log("JackWinThread::StartImp : create non RT thread"); } return 0; } // voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx int JackWinThread::Kill() { if (fThread != (HANDLE)NULL) { // If thread has been started TerminateThread(fThread, 0); WaitForSingleObject(fThread, INFINITE); CloseHandle(fThread); jack_log("JackWinThread::Kill"); fThread = (HANDLE)NULL; fStatus = kIdle; return 0; } else { return -1; } } int JackWinThread::Stop() { if (fThread != (HANDLE)NULL) { // If thread has been started jack_log("JackWinThread::Stop"); fStatus = kIdle; // Request for the thread to stop WaitForSingleObject(fEvent, INFINITE); CloseHandle(fThread); fThread = (HANDLE)NULL; return 0; } else { return -1; } } int JackWinThread::KillImp(jack_native_thread_t thread) { if (thread != (HANDLE)NULL) { // If thread has been started TerminateThread(thread, 0); WaitForSingleObject(thread, INFINITE); CloseHandle(thread); return 0; } else { return -1; } } int JackWinThread::StopImp(jack_native_thread_t thread) { if (thread) { // If thread has been started WaitForSingleObject(thread, INFINITE); CloseHandle(thread); return 0; } else { return -1; } } int JackWinThread::AcquireRealTime() { return (fThread != (HANDLE)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; } int JackWinThread::AcquireSelfRealTime() { return AcquireRealTimeImp(GetCurrentThread(), fPriority); } int JackWinThread::AcquireRealTime(int priority) { fPriority = priority; return AcquireRealTime(); } int JackWinThread::AcquireSelfRealTime(int priority) { fPriority = priority; return AcquireSelfRealTime(); } int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) { jack_log("JackWinThread::AcquireRealTimeImp priority = %d", priority); if (priority >= (BASE_REALTIME_PRIORITY - 1) && MMCSSAcquireRealTime(thread, priority) == 0) { jack_log("MMCSS API used to acquire RT for thread"); return 0; } else { jack_log("MMCSS API not used..."); if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { return 0; } else { jack_error("Cannot set thread priority = %d", GetLastError()); return -1; } } } int JackWinThread::DropRealTime() { return (fThread != (HANDLE)NULL) ? DropRealTimeImp(fThread) : -1; } int JackWinThread::DropSelfRealTime() { return DropRealTimeImp(GetCurrentThread()); } int JackWinThread::DropRealTimeImp(jack_native_thread_t thread) { if (MMCSSDropRealTime(thread) == 0) { jack_log("MMCSS API used to drop RT for thread"); return 0; } else if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) { return 0; } else { jack_error("Cannot set thread priority = %d", GetLastError()); return -1; } } jack_native_thread_t JackWinThread::GetThreadID() { return fThread; } bool JackWinThread::IsThread() { return GetCurrentThread() == fThread; } void JackWinThread::Terminate() { jack_log("JackWinThread::Terminate"); ExitThread(0); } SERVER_EXPORT void ThreadExit() { jack_log("ThreadExit"); ExitThread(0); } } // end of namespace bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr) { return false; } bool jack_tls_allocate_key(jack_tls_key *key_ptr) { DWORD key; key = TlsAlloc(); if (key == TLS_OUT_OF_INDEXES) { jack_error("TlsAlloc() failed. Error is %d", (unsigned int)GetLastError()); return false; } *key_ptr = key; return true; } bool jack_tls_free_key(jack_tls_key key) { if (!TlsFree(key)) { jack_error("TlsFree() failed. Error is %d", (unsigned int)GetLastError()); return false; } return true; } bool jack_tls_set(jack_tls_key key, void *data_ptr) { if (!TlsSetValue(key, data_ptr)) { jack_error("TlsSetValue() failed. Error is %d", (unsigned int)GetLastError()); return false; } return true; } void *jack_tls_get(jack_tls_key key) { return TlsGetValue(key); } 1.9.12~dfsg/windows/jack_netdriver.cbp0000644000000000000000000001316313214314510016516 0ustar rootroot 1.9.12~dfsg/windows/jack_load.cbp0000644000000000000000000001176213214314510015436 0ustar rootroot 1.9.12~dfsg/windows/JackWinNamedPipeClientChannel.cpp0000644000000000000000000001105613214314510021302 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackWinNamedPipeClientChannel.h" #include "JackRequest.h" #include "JackClient.h" #include "JackGlobals.h" #include "JackError.h" namespace Jack { JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel() :JackGenericClientChannel(),fThread(this) { fRequest = new JackWinNamedPipeClient(); } JackWinNamedPipeClientChannel::~JackWinNamedPipeClientChannel() { delete fRequest; } int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status) { int result = 0; jack_log("JackWinNamedPipeClientChannel::Open name = %s", name); /* 16/08/07: was called before doing "fRequest->Connect" .... still necessary? if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) { jack_error("Cannot bind pipe"); goto error; } */ // Before any server/client call fClient = client; if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) { jack_error("Cannot connect to server pipe"); goto error; } // OK so server is there... JackGlobals::fServerRunning = true; // Check name in server ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true); if (result < 0) { int status1 = *status; if (status1 & JackVersionError) { jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); } else { jack_error("Client name = %s conflits with another running client", name); } } if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) { jack_error("Cannot bind pipe"); goto error; } return 0; error: fRequest->Close(); fNotificationListenPipe.Close(); return -1; } void JackWinNamedPipeClientChannel::Close() { fRequest->Close(); fNotificationListenPipe.Close(); // Here the thread will correctly stop when the pipe are closed fThread.Stop(); } int JackWinNamedPipeClientChannel::Start() { jack_log("JackWinNamedPipeClientChannel::Start"); /* To be sure notification thread is started before ClientOpen is called. */ if (fThread.StartSync() != 0) { jack_error("Cannot start Jack client listener"); return -1; } else { return 0; } } void JackWinNamedPipeClientChannel::Stop() { jack_log("JackWinNamedPipeClientChannel::Stop"); fThread.Kill(); // Unsafe on WIN32... TODO : solve WIN32 thread Kill issue } bool JackWinNamedPipeClientChannel::Init() { jack_log("JackWinNamedPipeClientChannel::Init"); // Setup context if (!jack_tls_set(JackGlobals::fNotificationThread, this)) { jack_error("Failed to set thread notification key"); } if (!fNotificationListenPipe.Accept()) { jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe"); return false; } else { return true; } } bool JackWinNamedPipeClientChannel::Execute() { JackClientNotification event; JackResult res; if (event.Read(&fNotificationListenPipe) < 0) { jack_error("JackWinNamedPipeClientChannel read fail"); goto error; } res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); if (event.fSync) { if (res.Write(&fNotificationListenPipe) < 0) { jack_error("JackWinNamedPipeClientChannel write fail"); goto error; } } return true; error: // Close the pipes, server wont be able to create them otherwise. fNotificationListenPipe.Close(); fRequest->Close(); fClient->ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE); return false; } } // end of namespace 1.9.12~dfsg/windows/samplerate.h0000644000000000000000000001250213214314510015340 0ustar rootroot/* ** Copyright (C) 2002-2008 Erik de Castro Lopo ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* ** This code is part of Secret Rabibt Code aka libsamplerate. A commercial ** use license for this code is available, please see: ** http://www.mega-nerd.com/SRC/procedure.html */ /* ** API documentation is available here: ** http://www.mega-nerd.com/SRC/api.html */ #ifndef SAMPLERATE_H #define SAMPLERATE_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Opaque data type SRC_STATE. */ typedef struct SRC_STATE_tag SRC_STATE ; /* SRC_DATA is used to pass data to src_simple() and src_process(). */ typedef struct { float *data_in, *data_out ; long input_frames, output_frames ; long input_frames_used, output_frames_gen ; int end_of_input ; double src_ratio ; } SRC_DATA ; /* SRC_CB_DATA is used with callback based API. */ typedef struct { long frames ; float *data_in ; } SRC_CB_DATA ; /* ** User supplied callback function type for use with src_callback_new() ** and src_callback_read(). First parameter is the same pointer that was ** passed into src_callback_new(). Second parameter is pointer to a ** pointer. The user supplied callback function must modify *data to ** point to the start of the user supplied float array. The user supplied ** function must return the number of frames that **data points to. */ typedef long (*src_callback_t) (void *cb_data, float **data) ; /* ** Standard initialisation function : return an anonymous pointer to the ** internal state of the converter. Choose a converter from the enums below. ** Error returned in *error. */ SRC_STATE* src_new (int converter_type, int channels, int *error) ; /* ** Initilisation for callback based API : return an anonymous pointer to the ** internal state of the converter. Choose a converter from the enums below. ** The cb_data pointer can point to any data or be set to NULL. Whatever the ** value, when processing, user supplied function "func" gets called with ** cb_data as first parameter. */ SRC_STATE* src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data) ; /* ** Cleanup all internal allocations. ** Always returns NULL. */ SRC_STATE* src_delete (SRC_STATE *state) ; /* ** Standard processing function. ** Returns non zero on error. */ int src_process (SRC_STATE *state, SRC_DATA *data) ; /* ** Callback based processing function. Read up to frames worth of data from ** the converter int *data and return frames read or -1 on error. */ long src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data) ; /* ** Simple interface for performing a single conversion from input buffer to ** output buffer at a fixed conversion ratio. ** Simple interface does not require initialisation as it can only operate on ** a single buffer worth of audio. */ int src_simple (SRC_DATA *data, int converter_type, int channels) ; /* ** This library contains a number of different sample rate converters, ** numbered 0 through N. ** ** Return a string giving either a name or a more full description of each ** sample rate converter or NULL if no sample rate converter exists for ** the given value. The converters are sequentially numbered from 0 to N. */ const char *src_get_name (int converter_type) ; const char *src_get_description (int converter_type) ; const char *src_get_version (void) ; /* ** Set a new SRC ratio. This allows step responses ** in the conversion ratio. ** Returns non zero on error. */ int src_set_ratio (SRC_STATE *state, double new_ratio) ; /* ** Reset the internal SRC state. ** Does not modify the quality settings. ** Does not free any memory allocations. ** Returns non zero on error. */ int src_reset (SRC_STATE *state) ; /* ** Return TRUE if ratio is a valid conversion ratio, FALSE ** otherwise. */ int src_is_valid_ratio (double ratio) ; /* ** Return an error number. */ int src_error (SRC_STATE *state) ; /* ** Convert the error number into a string. */ const char* src_strerror (int error) ; /* ** The following enums can be used to set the interpolator type ** using the function src_set_converter(). */ enum { SRC_SINC_BEST_QUALITY = 0, SRC_SINC_MEDIUM_QUALITY = 1, SRC_SINC_FASTEST = 2, SRC_ZERO_ORDER_HOLD = 3, SRC_LINEAR = 4, } ; /* ** Extra helper functions for converting from short to float and ** back again. */ void src_short_to_float_array (const short *in, float *out, int len) ; void src_float_to_short_array (const float *in, short *out, int len) ; void src_int_to_float_array (const int *in, float *out, int len) ; void src_float_to_int_array (const float *in, int *out, int len) ; #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* SAMPLERATE_H */ 1.9.12~dfsg/windows/JackMMCSS.h0000644000000000000000000000373313214314510014664 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMMCSS__ #define __JackMMCSS__ #include "JackSystemDeps.h" #include "JackCompilerDeps.h" #include #include namespace Jack { typedef enum _AVRT_PRIORITY { AVRT_PRIORITY_LOW = -1, AVRT_PRIORITY_NORMAL, /* 0 */ AVRT_PRIORITY_HIGH, /* 1 */ AVRT_PRIORITY_CRITICAL /* 2 */ } AVRT_PRIORITY, *PAVRT_PRIORITY; #define BASE_REALTIME_PRIORITY 90 typedef HANDLE (WINAPI *avSetMmThreadCharacteristics)(LPCTSTR, LPDWORD); typedef BOOL (WINAPI *avRevertMmThreadCharacteristics)(HANDLE); typedef BOOL (WINAPI *avSetMmThreadPriority)(HANDLE, AVRT_PRIORITY); /*! \brief MMCSS services. */ class SERVER_EXPORT JackMMCSS { private: static JACK_HANDLE fAvrtDll; static avSetMmThreadCharacteristics ffMMCSSFun1; static avSetMmThreadPriority ffMMCSSFun2; static avRevertMmThreadCharacteristics ffMMCSSFun3; static std::map fHandleTable; public: JackMMCSS(); ~JackMMCSS(); static int MMCSSAcquireRealTime(jack_native_thread_t thread, int priority); static int MMCSSDropRealTime(jack_native_thread_t thread); }; } // end of namespace #endif 1.9.12~dfsg/windows/JackWinSemaphore.h0000644000000000000000000000330413214314510016375 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinSemaphore__ #define __JackWinSemaphore__ #include "JackSynchro.h" #include #include namespace Jack { /*! \brief Inter process synchronization using system wide semaphore. */ class JackWinSemaphore : public detail::JackSynchro { private: HANDLE fSemaphore; protected: void BuildName(const char* name, const char* server_name, char* res, int size); public: JackWinSemaphore():JackSynchro(), fSemaphore(NULL) {} bool Signal(); bool SignalAll(); bool Wait(); bool TimedWait(long usec); bool Allocate(const char* name, const char* server_name, int value); bool Connect(const char* name, const char* server_name); bool ConnectInput(const char* name, const char* server_name); bool ConnectOutput(const char* name, const char* server_name); bool Disconnect(); void Destroy(); }; } // end of namespace #endif 1.9.12~dfsg/windows/JackWinTime.c0000644000000000000000000000353713214314510015353 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackTime.h" #include "JackError.h" static LARGE_INTEGER _jack_freq; static UINT gPeriod = 0; SERVER_EXPORT void JackSleep(long usec) { Sleep(usec / 1000); } SERVER_EXPORT void InitTime() { TIMECAPS caps; QueryPerformanceFrequency(&_jack_freq); if (timeGetDevCaps(&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) { jack_error("InitTime : could not get timer device"); } else { gPeriod = caps.wPeriodMin; if (timeBeginPeriod(gPeriod) != TIMERR_NOERROR) { jack_error("InitTime : could not set minimum timer"); gPeriod = 0; } else { jack_log("InitTime : multimedia timer resolution set to %d milliseconds", gPeriod); } } } SERVER_EXPORT void EndTime() { if (gPeriod > 0) { timeEndPeriod(gPeriod); } } SERVER_EXPORT jack_time_t GetMicroSeconds(void) { LARGE_INTEGER t1; QueryPerformanceCounter(&t1); return (jack_time_t)(((double)t1.QuadPart) / ((double)_jack_freq.QuadPart) * 1000000.0); } void SetClockSource(jack_timer_type_t source) {} const char* ClockSourceName(jack_timer_type_t source) { return ""; } 1.9.12~dfsg/windows/JackCompilerDeps_os.h0000644000000000000000000000341313214314510017064 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackCompilerDeps_WIN32__ #define __JackCompilerDeps_WIN32__ #define LIB_EXPORT __declspec(dllexport) #ifdef SERVER_SIDE #define SERVER_EXPORT __declspec(dllexport) #else #define SERVER_EXPORT #endif #if __GNUC__ #define MEM_ALIGN(x,y) x __attribute__((aligned(y))) #else #define MEM_ALIGN(x,y) x #endif #if defined(_MSC_VER) /* Added by JE - 31-01-2012 */ #define strdup _strdup #if _MSC_VER < 1900 // This wrapper is not fully standard-compliant. _snprintf() does not // distinguish whether a result is truncated or a format error occurs. inline int vsnprintf(char* buf, size_t buf_len, const char* fmt, va_list args) { int str_len = _vsnprintf(buf, buf_len - 1, fmt, args); if (str_len == buf_len - 1 || str_len < 0) { buf[buf_len - 1] = '\0'; return buf_len - 1; } return str_len; } inline int snprintf(char* buf, size_t buf_len, const char* fmt, ...) { va_list args; va_start(args, fmt); int str_len = vsnprintf(buf, buf_len, fmt, args); va_end(args); return str_len; } #endif #endif #endif 1.9.12~dfsg/windows/JackNetWinSocket.h0000644000000000000000000000652213214314510016356 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackNetWinSocket__ #define __JackNetWinSocket__ #include "JackNetSocket.h" #ifdef __MINGW32__ #include #include #include #endif namespace Jack { #define E(code, s) { code, s } #define NET_ERROR_CODE WSAGetLastError() #define StrError PrintError typedef uint32_t uint; typedef int SOCKLEN; typedef struct _win_net_error win_net_error_t; struct _win_net_error { int code; const char* msg; }; SERVER_EXPORT const char* PrintError(int error); //JeckNetWinSocket*************************************************************************** class SERVER_EXPORT JackNetWinSocket { private: int fSockfd; int fPort; SOCKADDR_IN fSendAddr; SOCKADDR_IN fRecvAddr; public: JackNetWinSocket(); JackNetWinSocket(const char* ip, int port); JackNetWinSocket(const JackNetWinSocket&); ~JackNetWinSocket(); JackNetWinSocket& operator=(const JackNetWinSocket&); //socket management int NewSocket(); int Bind(); int BindWith(const char* ip); int BindWith(int port); int Connect(); int ConnectTo(const char* ip); void Close(); void Reset(); bool IsSocket(); //IP/PORT management void SetPort(int port); int GetPort(); //address management int SetAddress(const char* ip, int port); char* GetSendIP(); char* GetRecvIP(); //utility int GetName(char* name); int JoinMCastGroup(const char* mcast_ip); //options management int SetOption(int level, int optname, const void* optval, SOCKLEN optlen); int GetOption(int level, int optname, void* optval, SOCKLEN* optlen); //timeout int SetTimeOut(int usec); //disable local loop int SetLocalLoop(); bool IsLocal(char* ip); //network operations int SendTo(const void* buffer, size_t nbytes, int flags); int SendTo(const void* buffer, size_t nbytes, int flags, const char* ip); int Send(const void* buffer, size_t nbytes, int flags); int RecvFrom(void* buffer, size_t nbytes, int flags); int Recv(void* buffer, size_t nbytes, int flags); int CatchHost(void* buffer, size_t nbytes, int flags); //error management net_error_t GetError(); }; } #endif 1.9.12~dfsg/windows/JackWinNamedPipeNotifyChannel.h0000644000000000000000000000271213214314510021000 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinNamedPipeNotifyChannel__ #define __JackWinNamedPipeNotifyChannel__ #include "JackWinNamedPipe.h" namespace Jack { /*! \brief JackNotifyChannel using named pipe. */ class JackWinNamedPipeNotifyChannel { private: JackWinNamedPipeClient fNotifyPipe; // Pipe to communicate with the server : from server to client public: JackWinNamedPipeNotifyChannel() {} int Open(const char* name); // Open the Server/Client connection void Close(); // Close the Server/Client connection void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); }; } // end of namespace #endif 1.9.12~dfsg/windows/JackWinNamedPipe.h0000644000000000000000000001076613214314510016326 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinNamedPipe__ #define __JackWinNamedPipe__ #include #include "JackChannel.h" namespace Jack { class JackWinNamedPipeAux { protected: HANDLE fNamedPipe; char fName[256]; int ReadAux(void* data, int len); int WriteAux(void* data, int len); public: JackWinNamedPipeAux(): fNamedPipe(INVALID_HANDLE_VALUE) {} JackWinNamedPipeAux(HANDLE pipe): fNamedPipe(pipe) {} virtual ~JackWinNamedPipeAux() {} }; class JackWinNamedPipe : public JackWinNamedPipeAux, public detail::JackChannelTransactionInterface { public: JackWinNamedPipe():JackWinNamedPipeAux() {} JackWinNamedPipe(HANDLE pipe):JackWinNamedPipeAux(pipe) {} virtual ~JackWinNamedPipe() {} virtual int Read(void* data, int len) { return ReadAux(data, len); } virtual int Write(void* data, int len) { return WriteAux(data, len); } }; /*! \brief Client named pipe. */ class JackWinNamedPipeClient : public JackWinNamedPipeAux, public detail::JackClientRequestInterface { protected: int ConnectAux(); public: JackWinNamedPipeClient():JackWinNamedPipeAux() {} JackWinNamedPipeClient(HANDLE pipe, const char* name):JackWinNamedPipeAux(pipe) { strcpy(fName, name); } virtual ~JackWinNamedPipeClient() {} virtual int Connect(const char* dir, int which); virtual int Connect(const char* dir, const char* name, int which); virtual int Close(); virtual int Read(void* data, int len) { return ReadAux(data, len); } virtual int Write(void* data, int len) { return WriteAux(data, len); } virtual void SetReadTimeOut(long sec); virtual void SetWriteTimeOut(long sec); virtual void SetNonBlocking(bool onoff); }; class JackWinAsyncNamedPipeClient : public JackWinNamedPipeClient { enum kIOState {kIdle = 0, kConnecting, kReading, kWriting}; private: bool fPendingIO; kIOState fIOState; OVERLAPPED fOverlap; public: JackWinAsyncNamedPipeClient(); JackWinAsyncNamedPipeClient(HANDLE pipe, const char* name, bool pending); virtual ~JackWinAsyncNamedPipeClient(); virtual int Read(void* data, int len); virtual int Write(void* data, int len); HANDLE GetEvent() { return (HANDLE)fOverlap.hEvent; } kIOState GetIOState() { return fIOState; } bool GetPending() { return fPendingIO; } int FinishIO(); }; /*! \brief Server named pipe. */ class JackWinNamedPipeServer : public JackWinNamedPipe { private: int BindAux(); public: JackWinNamedPipeServer(): JackWinNamedPipe() {} virtual ~JackWinNamedPipeServer() {} virtual int Bind(const char* dir, int which); virtual int Bind(const char* dir, const char* name, int which); virtual bool Accept(); virtual JackWinNamedPipeClient* AcceptClient(); int Close(); }; /*! \brief Server async named pipe. */ class JackWinAsyncNamedPipeServer : public JackWinNamedPipeServer { private: int BindAux(); public: JackWinAsyncNamedPipeServer(): JackWinNamedPipeServer() {} virtual ~JackWinAsyncNamedPipeServer() {} int Bind(const char* dir, int which); int Bind(const char* dir, const char* name, int which); bool Accept(); JackWinNamedPipeClient* AcceptClient(); int Close(); }; } // end of namespace #endif 1.9.12~dfsg/windows/multiple_metro.cbp0000644000000000000000000001221013214314510016555 0ustar rootroot 1.9.12~dfsg/windows/libjacknet.cbp0000644000000000000000000002044413214314510015632 0ustar rootroot 1.9.12~dfsg/windows/jack_connect.cbp0000644000000000000000000001256213214314510016147 0ustar rootroot 1.9.12~dfsg/windows/jack_netonedriver.cbp0000644000000000000000000001350713214314510017222 0ustar rootroot 1.9.12~dfsg/windows/getopt1.c0000644000000000000000000001067713214314510014574 0ustar rootroot/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "getopt.h" #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char **argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* Not ELIDE_CODE. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ 1.9.12~dfsg/windows/jack_loopback.cbp0000644000000000000000000001406013214314510016303 0ustar rootroot 1.9.12~dfsg/windows/JackWinMutex.cpp0000644000000000000000000000707413214314510016117 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackWinMutex.h" #include "JackError.h" namespace Jack { bool JackBaseWinMutex::Lock() { if (fOwner != GetCurrentThreadId()) { DWORD res = WaitForSingleObject(fMutex, INFINITE); if (res == WAIT_OBJECT_0) { fOwner = GetCurrentThreadId(); return true; } else { jack_log("JackBaseWinMutex::Lock res = %d", res); return false; } } else { jack_error("JackBaseWinMutex::Lock mutex already locked by thread = %d", GetCurrentThreadId()); return false; } } bool JackBaseWinMutex::Trylock() { if (fOwner != GetCurrentThreadId()) { DWORD res = WaitForSingleObject(fMutex, 0); if (res == WAIT_OBJECT_0) { fOwner = GetCurrentThreadId(); return true; } else { jack_log("JackBaseWinMutex::Trylock res = %d", res); return false; } } else { jack_error("JackBaseWinMutex::Trylock mutex already locked by thread = %d", GetCurrentThreadId()); return false; } } bool JackBaseWinMutex::Unlock() { if (fOwner == GetCurrentThreadId()) { fOwner = 0; int res = ReleaseMutex(fMutex); if (res != 0) { return true; } else { jack_log("JackBaseWinMutex::Unlock res = %d", res); return false; } } else { jack_error("JackBaseWinMutex::Unlock mutex not locked by thread = %d", GetCurrentThreadId()); return false; } } bool JackWinMutex::Lock() { if (WAIT_OBJECT_0 == WaitForSingleObject(fMutex, INFINITE)) { return true; } else { jack_log("JackWinProcessSync::Lock WaitForSingleObject err = %d", GetLastError()); return false; } } bool JackWinMutex::Trylock() { if (WAIT_OBJECT_0 == WaitForSingleObject(fMutex, 0)) { return true; } else { jack_log("JackWinProcessSync::Trylock WaitForSingleObject err = %d", GetLastError()); return false; } } bool JackWinMutex::Unlock() { if (!ReleaseMutex(fMutex)) { jack_log("JackWinProcessSync::Unlock ReleaseMutex err = %d", GetLastError()); return false; } else { return true; } } bool JackWinCriticalSection::Lock() { EnterCriticalSection(&fSection); return true; } bool JackWinCriticalSection::Trylock() { return (TryEnterCriticalSection(&fSection)); } bool JackWinCriticalSection::Unlock() { LeaveCriticalSection(&fSection); return true; } } // namespace 1.9.12~dfsg/windows/JackTypes_os.h0000644000000000000000000000167313214314510015610 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackTypes_WIN32__ #define __JackTypes_WIN32__ #include typedef ULONGLONG UInt64; typedef UInt64 uint64_t; typedef unsigned short uint16_t; typedef DWORD jack_tls_key; #endif 1.9.12~dfsg/windows/libjackserver.cbp0000644000000000000000000003243213214314510016352 0ustar rootroot 1.9.12~dfsg/windows/JackWinServerLaunch.cpp0000644000000000000000000001734113214314510017414 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2011 John Emmas This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackChannel.h" #include "JackLibGlobals.h" #include "JackServerLaunch.h" #include "JackPlatformPlug.h" using namespace Jack; #include #include #include #include #include #if defined(_MSC_VER) || defined(__MINGW__) || defined(__MINGW32__) static char* find_path_to_jackdrc(char *path_to_jackdrc) { char user_jackdrc[1024]; char *ret = NULL; user_jackdrc[0] = user_jackdrc[1] = 0; // Initialise if (S_OK == SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, user_jackdrc)) { // The above call should have given us the path to the user's home folder char ch = user_jackdrc[strlen(user_jackdrc)-1]; if (('/' != ch) && ('\\' != ch)) strcat(user_jackdrc, "\\"); if (user_jackdrc[1] == ':') { // Assume we have a valid path strcat(user_jackdrc, ".jackdrc"); strcpy(path_to_jackdrc, user_jackdrc); ret = path_to_jackdrc; } else path_to_jackdrc[0] = '\0'; } else path_to_jackdrc[0] = '\0'; return (ret); } #else static char* find_path_to_jackdrc(char *path_to_jackdrc) { return 0; } #endif /* 'start_server_aux()' - this function might need to be modified (though probably * not) to cope with compilers other than MSVC (e.g. MinGW). The function * 'find_path_to_jackdrc()' might also need to be written for MinGW, though for * Cygwin, JackPosixServerLaunch.cpp can be used instead of this file. */ #include static int start_server_aux(const char* server_name) { FILE* fp = 0; size_t pos = 0; size_t result = 0; int i = 0; int good = 0; int ret = 0; char* command = 0; char** argv = 0; char* p; char* back_slash; char* forward_slash; char arguments [256]; char buffer [MAX_PATH]; char filename [MAX_PATH]; char curr_wd [MAX_PATH]; curr_wd[0] = '\0'; if (find_path_to_jackdrc(filename)) fp = fopen(filename, "r"); /* if still not found, check old config name for backwards compatability */ /* JE - hopefully won't be needed for the Windows build if (!fp) { fp = fopen("/etc/jackd.conf", "r"); } */ if (fp) { arguments[0] = '\0'; fgets(filename, MAX_PATH, fp); _strlwr(filename); if ((p = strstr(filename, ".exe"))) { p += 4; *p = '\0'; pos = (size_t)(p - filename); fseek(fp, 0, SEEK_SET); if ((command = (char*)malloc(pos+1))) ret = fread(command, 1, pos, fp); if (ret && !ferror(fp)) { command[pos] = '\0'; // NULL terminator back_slash = strrchr(command, '\\'); forward_slash = strrchr(command, '/'); if (back_slash > forward_slash) p = back_slash + 1; else p = forward_slash + 1; strcpy(buffer, p); while (ret != 0 && ret != EOF) { strcat(arguments, buffer); strcat(arguments, " "); ret = fscanf(fp, "%s", buffer); } if (strlen(arguments) > 0) { good = 1; } } } fclose(fp); } if (!good) { strcpy(buffer, JACK_LOCATION "/jackd.exe"); command = (char*)malloc((strlen(buffer))+1); strcpy(command, buffer); strncpy(arguments, "jackd.exe -S -d " JACK_DEFAULT_DRIVER, 255); } int buffer_termination; bool verbose_mode = false; argv = (char**)malloc(255); pos = 0; while (1) { /* insert -T and -n server_name in front of arguments */ if (i == 1) { argv[i] = (char*)malloc(strlen ("-T") + 1); strcpy (argv[i++], "-T"); if (server_name) { size_t optlen = strlen("-n"); char* buf = (char*)malloc(optlen + strlen(server_name) + 1); strcpy(buf, "-n"); strcpy(buf + optlen, server_name); argv[i++] = buf; } } // Only get the next character if there's more than 1 character if ((pos < strlen(arguments)) && (arguments[pos+1]) && (arguments[pos+1] != ' ')) { strncpy(buffer, arguments + pos++, 1); buffer_termination = 1; } else { buffer[0] = '\0'; buffer_termination = 0; } buffer[1] = '\0'; if (buffer[0] == '\"') result = strcspn(arguments + pos, "\""); else result = strcspn(arguments + pos, " "); if (0 == result) break; else { strcat(buffer, arguments + pos); // Terminate the buffer buffer[result + buffer_termination] = '\0'; if (buffer[0] == '\"') { strcat(buffer, "\""); ++result; } argv[i] = (char*)malloc(strlen(buffer) + 1); strcpy(argv[i], buffer); pos += (result + 1); ++i; if ((0 == strcmp(buffer, "-v")) || (0 == strcmp(buffer, "--verbose"))) verbose_mode = true; } } argv[i] = 0; #ifdef SUPPORT_PRE_1_9_8_SERVER // Get the current working directory if (_getcwd(curr_wd, MAX_PATH)) { strcpy(temp_wd, command); back_slash = strrchr(temp_wd, '\\'); forward_slash = strrchr(temp_wd, '/'); if (back_slash > forward_slash) p = back_slash; else p = forward_slash; *p = '\0'; // Accommodate older versions of Jack (pre v1.9.8) which // might need to be started from their installation folder. _chdir(temp_wd); } #endif if (verbose_mode) { // Launch the server with a console... (note that // if the client is a console app, the server might // also use the client's console) ret = _spawnv(_P_NOWAIT, command, argv); } else { // Launch the server silently... (without a console) ret = _spawnv(_P_DETACH, command, argv); } Sleep(2500); // Give it some time to launch if ((-1) == ret) fprintf(stderr, "Execution of JACK server (command = \"%s\") failed: %s\n", command, strerror(errno)); if (strlen(curr_wd)) { // Change the cwd back to its original setting _chdir(curr_wd); } if (command) free(command); if (argv) { for (i = 0; argv[i] != 0; i++) free (argv[i]); free(argv); } return (ret == (-1) ? false : true); } static int start_server(const char* server_name, jack_options_t options) { if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) { return 1; } return (((-1) != (start_server_aux(server_name)) ? 0 : (-1))); } static int server_connect(const char* server_name) { JackClientChannel channel; int res = channel.ServerCheck(server_name); channel.Close(); /* JackSleep(2000); // Added by JE - 02-01-2009 (gives // the channel some time to close) */ JackSleep(500); return res; } int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status) { if (server_connect(va->server_name) < 0) { int trys; if (start_server(va->server_name, options)) { int my_status1 = *status | JackFailure | JackServerFailed; *status = (jack_status_t)my_status1; return -1; } trys = 5; do { Sleep(1000); if (--trys < 0) { int my_status1 = *status | JackFailure | JackServerFailed; *status = (jack_status_t)my_status1; return -1; } } while (server_connect(va->server_name) < 0); int my_status1 = *status | JackServerStarted; *status = (jack_status_t)my_status1; } return 0; } 1.9.12~dfsg/windows/JackWinNamedPipe.cpp0000644000000000000000000003236213214314510016655 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackWinNamedPipe.h" #include "JackError.h" #include #include #define BUFSIZE 4096 namespace Jack { int JackWinNamedPipeAux::ReadAux(void* data, int len) { DWORD read; BOOL res = ReadFile(fNamedPipe, data, len, &read, NULL); if (res && read == (DWORD)len) { return 0; } else { jack_log("Cannot read named pipe name = %s err = %ld", fName, GetLastError()); return -1; } } int JackWinNamedPipeAux::WriteAux(void* data, int len) { DWORD written; BOOL res = WriteFile(fNamedPipe, data, len, &written, NULL); if (res && written == (DWORD)len) { return 0; } else { jack_log("Cannot write named pipe name = %s err = %ld", fName, GetLastError()); return -1; } } /* See : http://answers.google.com/answers/threadview?id=430173 http://msdn.microsoft.com/en-us/library/windows/desktop/aa365800(v=vs.85).aspx */ /* int JackWinNamedPipeClient::ConnectAux() { fNamedPipe = CreateFile(fName, // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing NULL, // default security attributes OPEN_EXISTING, // opens existing pipe 0, // default attributes NULL); // no template file if (fNamedPipe == INVALID_HANDLE_VALUE) { jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError()); return -1; } else { return 0; } } */ int JackWinNamedPipeClient::ConnectAux() { jack_log("JackWinNamedPipeClient::ConnectAux : fName %s", fName); while (true) { fNamedPipe = CreateFile(fName, // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing NULL, // default security attributes OPEN_EXISTING, // opens existing pipe 0, // default attributes NULL); // no template file // Break if the pipe handle is valid. if (fNamedPipe != INVALID_HANDLE_VALUE) { return 0; } // Exit if an error other than ERROR_PIPE_BUSY or ERROR_FILE_NOT_FOUND occurs. if ((GetLastError() != ERROR_PIPE_BUSY) && (GetLastError() != ERROR_FILE_NOT_FOUND)) { jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError()); return -1; } // All pipe instances are busy, so wait for 2 seconds. if (!WaitNamedPipe(fName, 2000)) { jack_error("Cannot connect to named pipe after wait = %s err = %ld", fName, GetLastError()); return -1; } } } int JackWinNamedPipeClient::Connect(const char* dir, int which) { snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%d", dir, which); return ConnectAux(); } int JackWinNamedPipeClient::Connect(const char* dir, const char* name, int which) { snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which); return ConnectAux(); } int JackWinNamedPipeClient::Close() { if (fNamedPipe != INVALID_HANDLE_VALUE) { CloseHandle(fNamedPipe); fNamedPipe = INVALID_HANDLE_VALUE; return 0; } else { return -1; } } void JackWinNamedPipeClient::SetReadTimeOut(long sec) { /* COMMTIMEOUTS timeout; if (GetCommTimeouts(fNamedPipe, &timeout)) { jack_info("JackWinNamedPipeClient::SetReadTimeOut ReadIntervalTimeout = %d", timeout.ReadIntervalTimeout); jack_info("JackWinNamedPipeClient::SetReadTimeOut ReadTotalTimeoutMultiplier = %d", timeout.ReadTotalTimeoutMultiplier); jack_info("JackWinNamedPipeClient::SetReadTimeOut ReadTotalTimeoutConstant = %d", timeout.ReadTotalTimeoutConstant); } else { jack_error("JackWinNamedPipeClient::SetReadTimeOut err %d", GetLastError()); } */ } void JackWinNamedPipeClient::SetWriteTimeOut(long sec) { /* COMMTIMEOUTS timeout; if (GetCommTimeouts(fNamedPipe, &timeout)) { jack_info("JackWinNamedPipeClient::SetWriteTimeOut WriteTotalTimeoutMultiplier = %d", timeout.WriteTotalTimeoutMultiplier); jack_info("JackWinNamedPipeClient::SetWriteTimeOut WriteTotalTimeoutConstant = %d", timeout.WriteTotalTimeoutConstant); } */ } void JackWinNamedPipeClient::SetNonBlocking(bool onoff) {} JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient() : JackWinNamedPipeClient(), fPendingIO(false), fIOState(kIdle) { fIOState = kIdle; fOverlap.hEvent = CreateEvent(NULL, // default security attribute TRUE, // manual-reset event TRUE, // initial state = signaled NULL); // unnamed event object } JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient(HANDLE pipe, const char* name, bool pending) : JackWinNamedPipeClient(pipe, name), fPendingIO(pending), fIOState(kIdle) { fOverlap.hEvent = CreateEvent(NULL, // default security attribute TRUE, // manual-reset event TRUE, // initial state = signaled NULL); // unnamed event object if (!fPendingIO) { SetEvent(fOverlap.hEvent); } fIOState = (fPendingIO) ? kConnecting : kReading; } JackWinAsyncNamedPipeClient::~JackWinAsyncNamedPipeClient() { CloseHandle(fOverlap.hEvent); } int JackWinAsyncNamedPipeClient::FinishIO() { DWORD success, ret; success = GetOverlappedResult(fNamedPipe, // handle to pipe &fOverlap, // OVERLAPPED structure &ret, // bytes transferred FALSE); // do not wait switch (fIOState) { case kConnecting: if (!success) { jack_error("Conection error"); return -1; } else { fIOState = kReading; // Prepare connection for new client ?? } break; case kReading: if (!success || ret == 0) { return -1; } fIOState = kWriting; break; case kWriting: if (!success || ret == 0) { return -1; } fIOState = kReading; break; default: break; } return 0; } int JackWinAsyncNamedPipeClient::Read(void* data, int len) { DWORD read; jack_log("JackWinNamedPipeClient::Read len = %ld", len); BOOL res = ReadFile(fNamedPipe, data, len, &read, &fOverlap); if (res && read != 0) { fPendingIO = false; fIOState = kWriting; return 0; } else if (!res && GetLastError() == ERROR_IO_PENDING) { fPendingIO = true; return 0; } else { jack_error("Cannot read named pipe err = %ld", GetLastError()); return -1; } } int JackWinAsyncNamedPipeClient::Write(void* data, int len) { DWORD written; jack_log("JackWinNamedPipeClient::Write len = %ld", len); BOOL res = WriteFile(fNamedPipe, data, len, &written, &fOverlap); if (res && written != 0) { fPendingIO = false; fIOState = kWriting; return 0; } else if (!res && GetLastError() == ERROR_IO_PENDING) { fPendingIO = true; return 0; } else { jack_error("Cannot write named pipe err = %ld", GetLastError()); return -1; } } // Server side int JackWinNamedPipeServer::BindAux() { jack_log("JackWinNamedPipeServer::BindAux : fName %s", fName); if ((fNamedPipe = CreateNamedPipe(fName, PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances BUFSIZE, // output buffer size BUFSIZE, // input buffer size INFINITE, // client time-out NULL)) == INVALID_HANDLE_VALUE) { // no security jack_error("Cannot bind server to pipe err = %ld", GetLastError()); return -1; } else { return 0; } } int JackWinNamedPipeServer::Bind(const char* dir, int which) { snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%d", dir, which); return BindAux(); } int JackWinNamedPipeServer::Bind(const char* dir, const char* name, int which) { snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which); return BindAux(); } bool JackWinNamedPipeServer::Accept() { if (ConnectNamedPipe(fNamedPipe, NULL)) { return true; } else { jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError()); if (GetLastError() == ERROR_PIPE_CONNECTED) { jack_error("Pipe already connnected = %s", fName); return true; } else { return false; } } } JackWinNamedPipeClient* JackWinNamedPipeServer::AcceptClient() { if (ConnectNamedPipe(fNamedPipe, NULL)) { JackWinNamedPipeClient* client = new JackWinNamedPipeClient(fNamedPipe, fName); // Init the pipe to the default value fNamedPipe = INVALID_HANDLE_VALUE; return client; } else { switch (GetLastError()) { case ERROR_PIPE_CONNECTED: return new JackWinNamedPipeClient(fNamedPipe, fName); default: jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError()); return NULL; } } } int JackWinNamedPipeServer::Close() { jack_log("JackWinNamedPipeServer::Close"); if (fNamedPipe != INVALID_HANDLE_VALUE) { DisconnectNamedPipe(fNamedPipe); CloseHandle(fNamedPipe); fNamedPipe = INVALID_HANDLE_VALUE; return 0; } else { return -1; } } // Server side int JackWinAsyncNamedPipeServer::BindAux() { jack_log("JackWinAsyncNamedPipeServer::BindAux : fName %s", fName); if ((fNamedPipe = CreateNamedPipe(fName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances BUFSIZE, // output buffer size BUFSIZE, // input buffer size INFINITE, // client time-out NULL)) == INVALID_HANDLE_VALUE) { // no security a jack_error("Cannot bind server to pipe err = %ld", GetLastError()); return -1; } else { return 0; } } int JackWinAsyncNamedPipeServer::Bind(const char* dir, int which) { snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%d", dir, which); return BindAux(); } int JackWinAsyncNamedPipeServer::Bind(const char* dir, const char* name, int which) { snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which); return BindAux(); } bool JackWinAsyncNamedPipeServer::Accept() { return false; } JackWinNamedPipeClient* JackWinAsyncNamedPipeServer::AcceptClient() { if (ConnectNamedPipe(fNamedPipe, NULL)) { return new JackWinAsyncNamedPipeClient(fNamedPipe, fName, false); } else { switch (GetLastError()) { case ERROR_IO_PENDING: return new JackWinAsyncNamedPipeClient(fNamedPipe, fName, true); case ERROR_PIPE_CONNECTED: return new JackWinAsyncNamedPipeClient(fNamedPipe, fName, false); default: jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError()); return NULL; break; } } } } // end of namespace 1.9.12~dfsg/windows/JackWinNamedPipeServerChannel.cpp0000644000000000000000000001651613214314510021340 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackWinNamedPipeServerChannel.h" #include "JackNotification.h" #include "JackRequest.h" #include "JackServer.h" #include "JackLockedEngine.h" #include "JackGlobals.h" #include "JackClient.h" #include "JackNotification.h" #include "JackException.h" #include using namespace std; namespace Jack { HANDLE JackClientPipeThread::fMutex = NULL; // Never released.... // fRefNum = -1 correspond to already removed client JackClientPipeThread::JackClientPipeThread(JackWinNamedPipeClient* pipe) :fPipe(pipe), fDecoder(NULL), fServer(NULL), fThread(this), fRefNum(0) { // First one allocated the static fMutex if (fMutex == NULL) { fMutex = CreateMutex(NULL, FALSE, NULL); } } JackClientPipeThread::~JackClientPipeThread() { jack_log("JackClientPipeThread::~JackClientPipeThread"); delete fPipe; } int JackClientPipeThread::Open(JackServer* server) // Open the Server/Client connection { // Start listening if (fThread.Start() != 0) { jack_error("Cannot start Jack server listener\n"); return -1; } else { fDecoder = new JackRequestDecoder(server, this); fServer = server; return 0; } } void JackClientPipeThread::Close() // Close the Server/Client connection { jack_log("JackClientPipeThread::Close 0 %x %ld", this, fRefNum); //fThread.Kill(); fPipe->Close(); fRefNum = -1; delete fDecoder; fDecoder = NULL; } bool JackClientPipeThread::Execute() { try { jack_log("JackClientPipeThread::Execute %x", this); JackRequest header; int res = header.Read(fPipe); bool ret = true; // Lock the global mutex if (WaitForSingleObject(fMutex, INFINITE) == WAIT_FAILED) { jack_error("JackClientPipeThread::Execute : mutex wait error"); } // Decode header if (res < 0) { jack_log("JackClientPipeThread::Execute : cannot decode header"); ClientKill(); ret = false; // Decode request } else if (fDecoder->HandleRequest(fPipe, header.fType) < 0) { ret = false; } // Unlock the global mutex if (!ReleaseMutex(fMutex)) { jack_error("JackClientPipeThread::Execute : mutex release error"); } return ret; } catch (JackQuitException& e) { jack_log("JackClientPipeThread::Execute : JackQuitException"); return false; } } void JackClientPipeThread::ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult *res) { jack_log("JackClientPipeThread::ClientAdd %x %s", this, req->fName); fRefNum = -1; res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &fRefNum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph); } void JackClientPipeThread::ClientRemove(detail::JackChannelTransactionInterface* socket_aux, int refnum) { jack_log("JackClientPipeThread::ClientRemove ref = %d", refnum); Close(); } void JackClientPipeThread::ClientKill() { jack_log("JackClientPipeThread::ClientKill ref = %d", fRefNum); if (fRefNum == -1) { // Correspond to an already removed client. jack_log("Kill a closed client %x", this); } else if (fRefNum == 0) { // Correspond to a still not opened client. jack_log("Kill a not opened client %x", this); } else { fServer->GetEngine()->ClientKill(fRefNum); } Close(); } JackWinNamedPipeServerChannel::JackWinNamedPipeServerChannel():fThread(this) {} JackWinNamedPipeServerChannel::~JackWinNamedPipeServerChannel() { std::list::iterator it; for (it = fClientList.begin(); it != fClientList.end(); it++) { JackClientPipeThread* client = *it; client->Close(); delete client; } } int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* server) { jack_log("JackWinNamedPipeServerChannel::Open"); snprintf(fServerName, sizeof(fServerName), server_name); // Needed for internal connection from JackWinNamedPipeServerNotifyChannel object if (ClientListen()) { fServer = server; return 0; } else { jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe"); return -1; } } void JackWinNamedPipeServerChannel::Close() { /* TODO : solve WIN32 thread Kill issue This would hang the server... since we are quitting it, its not really problematic, all ressources will be deallocated at the end. fRequestListenPipe.Close(); fThread.Stop(); */ fRequestListenPipe.Close(); } int JackWinNamedPipeServerChannel::Start() { if (fThread.Start() != 0) { jack_error("Cannot start Jack server listener"); return -1; } else { return 0; } } void JackWinNamedPipeServerChannel::Stop() { fThread.Kill(); } bool JackWinNamedPipeServerChannel::Init() { jack_log("JackWinNamedPipeServerChannel::Init"); // Accept first client, that is the JackWinNamedPipeServerNotifyChannel object return ClientAccept(); } bool JackWinNamedPipeServerChannel::ClientListen() { if (fRequestListenPipe.Bind(jack_server_dir, fServerName, 0) < 0) { jack_error("JackWinNamedPipeServerChannel::ClientListen : cannot create result listen pipe"); return false; } else { return true; } } bool JackWinNamedPipeServerChannel::ClientAccept() { JackWinNamedPipeClient* pipe; if ((pipe = fRequestListenPipe.AcceptClient()) == NULL) { jack_error("JackWinNamedPipeServerChannel::ClientAccept : cannot connect pipe"); return false; } else { ClientAdd(pipe); return true; } } bool JackWinNamedPipeServerChannel::Execute() { if (!ClientListen()) { return false; } return ClientAccept(); } void JackWinNamedPipeServerChannel::ClientAdd(JackWinNamedPipeClient* pipe) { // Remove dead (= not running anymore) clients. std::list::iterator it = fClientList.begin(); JackClientPipeThread* client; jack_log("JackWinNamedPipeServerChannel::ClientAdd size %ld", fClientList.size()); while (it != fClientList.end()) { client = *it; if (client->IsRunning()) { it++; } else { it = fClientList.erase(it); delete client; } } client = new JackClientPipeThread(pipe); client->Open(fServer); // Here we are sure that the client is running (because it's thread is in "running" state). fClientList.push_back(client); } } // end of namespace 1.9.12~dfsg/windows/README0000644000000000000000000000732413214314510013720 0ustar rootroot------------------------------- JACK2 on Windows ------------------------------- This folder contains all the windows specific sources. You will also find two sets of files : - VisualC++6 workspace and project files, in order to compile JACK with MSVC - Code::Blocks (10.05) workspace and project files, in order to compile JACK with MingW The built binaries will be located in '/Release/bin' (or '/Debug/bin' if you build the Debug target). Once compiled, you'll find there everything you need : - the two 'libjack.dll' and 'libjackserver.dll', client and server jack libraries. - the 'jackd.exe', main application : the JACK server - the 'jack_xxx.exe' utilities and examples - in the jack directory, you'll find the driver's DLL's ('jack_portaudio.dll', 'jack_dummy.dll', 'jack_winmme.dll', 'jack_net.dll' and 'jack_netone.dll') and some tools ('netmanager.dll', 'audioadapter.dll', 'netadapter.dll' for example) In Code::Blocks all the projects are automatically built in a correct order (DLL's then apps) by doing 'build->build workspace'. In VC6, you'll have to build the projects one by one. The needed regexp library TRE can be found here http://laurikari.net/tre/. Unzip and place the "tre-0.8.0" folder into the "windows" folder. Then edit and comment "#define snprintf sprintf_s" at the end off the "tre-0.8.0/win32/config.h" file before building the JACK project. ------------------------------- Notes about VC and GCC versions ------------------------------- The Visual Studio workspace is limited to VC6. JACK will not compile on most recent MSVC's. The fact is recent compilers (MSVC7, 8 or 9) don't agree with some of the JACK sources. But now you can compile JACK using GCC, with MingW. The project is actually organized in a Code::Blocks workspace. This is a simple and efficient way to compile the whole project. But for some reasons, you need to compile JACK using a SJLJ version of G++ (available on MingW website). Current GCC/G++ version (3.4.5) doesn't includes SJLJ so you'll have to use another one. JACK needs the use of SJLJ exceptions instead of DW2 because exceptions are exchanged between DLL's, and DW2 does not allow to throw an exception out of a DLL, so it wouldn't be cought. The ressources files has been created with ResEdit (ANSI build). VisualStudio uses 'ressource.rc' and 'ressource_vc.h'. The other files are used by MingW. You can make a small installer ('setup.exe') with CreateInstallFree, a little freeware. For this you have the little script 'jack.ci' for 32 bits version and 'jack64.c' for mixed 64/32 bits version. The installer contains everything jack needs to be integrated in windows (including register entries and shortcuts). A binary version of QJAckCtl is also included. ------------------------------- Running JACK on Windows ------------------------------- You can use two drivers : PortAudio and NetDriver. The PortAudio backend allows the use of many soundcards, using ASIO, DirectSound or WMME drivers (any ASIO driver can be seen by PortAudio). The NetDriver allows you to use NetJack2 on windows. Thus you can easily exchange midi and audio streams between computers (Linux, MacOSX or Windows). In both cases, you have to use the minimalist : 'jackd -R -d ...' command. With PortAudio, you can have a list of supported drivers with : 'jackd -R -S -d portaudio -l' Other options still stay the same. You can also pick a binary of Qjackctl, but this is still in development. ------------------------------- Running Jack on windows ------------------------------- More information at : 'http://www.grame.fr/~letz/jackdmp.html'. For any question or suggestion, you can refer to the mailing list 'jack-devel@jackaudio.org' Enjoy JACK on windows... ;-) 1.9.12~dfsg/windows/JackWinNamedPipeServerNotifyChannel.cpp0000644000000000000000000000370113214314510022521 0ustar rootroot/* Copyright (C) 2004-2006 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackWinNamedPipeServerNotifyChannel.h" #include "JackError.h" #include "JackRequest.h" #include "JackConstants.h" #include "JackNotification.h" namespace Jack { int JackWinNamedPipeServerNotifyChannel::Open(const char* server_name) { if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) { jack_error("Cannot connect to server pipe"); return -1; } else { return 0; } } void JackWinNamedPipeServerNotifyChannel::Close() { fRequestPipe.Close(); } /* The requirement is that the Notification from RT thread can be delivered... not sure using a pipe is adequate here... Can the write operation block? A non blocking write operation shoud be used : check if write can succeed, and ignore the notification otherwise (since its mainly used for XRun, ignoring a notification is OK, successive XRun will come...) */ void JackWinNamedPipeServerNotifyChannel::Notify(int refnum, int notify, int value) { JackClientNotificationRequest req(refnum, notify, value); if (req.Write(&fRequestPipe) < 0) { jack_error("Could not write notification ref = %d notify = %d", refnum, notify); } } void JackWinNamedPipeServerNotifyChannel::NotifyQuit() { Notify(-1, kQUIT, 0); } } // end of namespace 1.9.12~dfsg/windows/jack_audioadapter.cbp0000644000000000000000000001623213214314510017156 0ustar rootroot 1.9.12~dfsg/windows/JackWinSemaphore.cpp0000644000000000000000000001054013214314510016730 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackWinSemaphore.h" #include "JackConstants.h" #include "JackTools.h" #include "JackError.h" #include namespace Jack { void JackWinSemaphore::BuildName(const char* client_name, const char* server_name, char* res, int size) { char ext_client_name[SYNC_MAX_NAME_SIZE + 1]; JackTools::RewriteName(client_name, ext_client_name); _snprintf(res, size, "jack_pipe.%s_%s", server_name, ext_client_name); } bool JackWinSemaphore::Signal() { BOOL res; assert(fSemaphore); if (fFlush) { return true; } if (!(res = ReleaseSemaphore(fSemaphore, 1, NULL))) { jack_error("JackWinSemaphore::Signal name = %s err = %ld", fName, GetLastError()); } return res; } bool JackWinSemaphore::SignalAll() { BOOL res; assert(fSemaphore); if (fFlush) { return true; } if (!(res = ReleaseSemaphore(fSemaphore, 1, NULL))) { jack_error("JackWinSemaphore::SignalAll name = %s err = %ld", fName, GetLastError()); } return res; } bool JackWinSemaphore::Wait() { DWORD res; if ((res = WaitForSingleObject(fSemaphore, INFINITE)) == WAIT_TIMEOUT) { jack_error("JackWinSemaphore::TimedWait name = %s time_out", fName); } return (res == WAIT_OBJECT_0); } bool JackWinSemaphore::TimedWait(long usec) { DWORD res; if ((res = WaitForSingleObject(fSemaphore, usec / 1000)) == WAIT_TIMEOUT) { jack_error("JackWinSemaphore::TimedWait name = %s time_out", fName); } return (res == WAIT_OBJECT_0); } // Client side : get the published semaphore from server bool JackWinSemaphore::ConnectInput(const char* name, const char* server_name) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackWinSemaphore::Connect %s", fName); // Temporary... if (fSemaphore) { jack_log("Already connected name = %s", name); return true; } if ((fSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS , FALSE, fName)) == NULL) { jack_error("Connect: can't check in named event name = %s err = %ld", fName, GetLastError()); return false; } else { return true; } } bool JackWinSemaphore::Connect(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackWinSemaphore::ConnectOutput(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackWinSemaphore::Disconnect() { if (fSemaphore) { jack_log("JackWinSemaphore::Disconnect %s", fName); CloseHandle(fSemaphore); fSemaphore = NULL; return true; } else { return false; } } bool JackWinSemaphore::Allocate(const char* name, const char* server_name, int value) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackWinSemaphore::Allocate name = %s val = %ld", fName, value); if ((fSemaphore = CreateSemaphore(NULL, value, 32767, fName)) == NULL) { jack_error("Allocate: can't check in named semaphore name = %s err = %ld", fName, GetLastError()); return false; } else if (GetLastError() == ERROR_ALREADY_EXISTS) { jack_error("Allocate: named semaphore already exist name = %s", fName); // Try to open it fSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, fName); return (fSemaphore != NULL); } else { return true; } } void JackWinSemaphore::Destroy() { if (fSemaphore != NULL) { jack_log("JackWinSemaphore::Destroy %s", fName); CloseHandle(fSemaphore); fSemaphore = NULL; } else { jack_error("JackWinSemaphore::Destroy synchro == NULL"); } } } // end of namespace 1.9.12~dfsg/windows/JackMMCSS.cpp0000644000000000000000000000542213214314510015214 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMMCSS.h" #include "JackError.h" #include #include namespace Jack { avSetMmThreadCharacteristics JackMMCSS::ffMMCSSFun1 = NULL; avSetMmThreadPriority JackMMCSS::ffMMCSSFun2 = NULL; avRevertMmThreadCharacteristics JackMMCSS::ffMMCSSFun3 = NULL; JACK_HANDLE JackMMCSS::fAvrtDll; std::map JackMMCSS::fHandleTable; JackMMCSS::JackMMCSS() { fAvrtDll = LoadJackModule("avrt.dll"); if (fAvrtDll != NULL) { ffMMCSSFun1 = (avSetMmThreadCharacteristics)GetJackProc(fAvrtDll, "AvSetMmThreadCharacteristicsA"); ffMMCSSFun2 = (avSetMmThreadPriority)GetJackProc(fAvrtDll, "AvSetMmThreadPriority"); ffMMCSSFun3 = (avRevertMmThreadCharacteristics)GetJackProc(fAvrtDll, "AvRevertMmThreadCharacteristics"); } } JackMMCSS::~JackMMCSS() {} int JackMMCSS::MMCSSAcquireRealTime(jack_native_thread_t thread, int priority) { if (fHandleTable.find(thread) != fHandleTable.end()) { return 0; } if (ffMMCSSFun1) { DWORD dummy = 0; HANDLE task = ffMMCSSFun1("Pro Audio", &dummy); if (task == NULL) { jack_error("AvSetMmThreadCharacteristics error : %d", GetLastError()); } else if (ffMMCSSFun2(task, Jack::AVRT_PRIORITY(priority - BASE_REALTIME_PRIORITY))) { fHandleTable[thread] = task; jack_log("AvSetMmThreadPriority success"); return 0; } else { jack_error("AvSetMmThreadPriority error : %d", GetLastError()); } } return -1; } int JackMMCSS::MMCSSDropRealTime(jack_native_thread_t thread) { if (fHandleTable.find(thread) != fHandleTable.end()) { HANDLE task = fHandleTable[thread]; if (ffMMCSSFun3(task) == 0) { jack_error("AvRevertMmThreadCharacteristics error : %d", GetLastError()); } else { jack_log("AvRevertMmThreadCharacteristics success"); } return 0; } else { return -1; } } } 1.9.12~dfsg/windows/jack_latent_client.cbp0000644000000000000000000001172013214314510017336 0ustar rootroot 1.9.12~dfsg/windows/resource.h0000644000000000000000000000006313214314510015031 0ustar rootroot#ifndef IDC_STATIC #define IDC_STATIC (-1) #endif 1.9.12~dfsg/windows/jack_portaudio.cbp0000644000000000000000000001746513214314510016533 0ustar rootroot 1.9.12~dfsg/windows/jack_netmanager.cbp0000644000000000000000000001334113214314510016633 0ustar rootroot 1.9.12~dfsg/windows/JackWinNamedPipeServerNotifyChannel.h0000644000000000000000000000247313214314510022173 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackWinNamedPipeServerNotifyChannel__ #define __JackWinNamedPipeServerNotifyChannel__ #include "JackChannel.h" #include "JackWinNamedPipe.h" namespace Jack { /*! \brief JackServerNotifyChannel using pipes. */ class JackWinNamedPipeServerNotifyChannel { private: JackWinNamedPipeClient fRequestPipe; public: JackWinNamedPipeServerNotifyChannel() {} int Open(const char* server_name); void Close(); void Notify(int refnum, int notify, int value); void NotifyQuit(); }; } // end of namespace #endif 1.9.12~dfsg/windows/jack_metro.cbp0000644000000000000000000001212313214314510015635 0ustar rootroot 1.9.12~dfsg/windows/libjack.cbp0000644000000000000000000003221213214314510015117 0ustar rootroot 1.9.12~dfsg/windows/jack_disconnect.cbp0000644000000000000000000001256513214314510016652 0ustar rootroot 1.9.12~dfsg/windows/getopt.h0000644000000000000000000001434413214314510014513 0ustar rootroot/* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GETOPT_H #ifndef __need_getopt # define _GETOPT_H 1 #endif #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; #ifndef __need_getopt /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { # if defined __STDC__ && __STDC__ const char *name; # else char *name; # endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ # define no_argument 0 # define required_argument 1 # define optional_argument 2 #endif /* need getopt */ /* Get definitions and prototypes for functions to process the arguments in ARGV (ARGC of them, minus the program name) for options given in OPTS. Return the option character from OPTS just read. Return -1 when there are no more options. For unrecognized options, or options missing arguments, `optopt' is set to the option letter, and '?' is returned. The OPTS string is a list of characters which are recognized option letters, optionally followed by colons, specifying that that letter takes an argument, to be placed in `optarg'. If a letter in OPTS is followed by two colons, its argument is optional. This behavior is specific to the GNU `getopt'. The argument `--' causes premature termination of argument scanning, explicitly telling `getopt' that there are no more options. If OPTS begins with `--', then non-option arguments are treated as arguments to the option '\0'. This behavior is specific to the GNU `getopt'. */ #if defined __STDC__ && __STDC__ # ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int __argc, char *const *__argv, const char *__shortopts); # else /* not __GNU_LIBRARY__ */ extern int getopt (); # endif /* __GNU_LIBRARY__ */ # ifndef __need_getopt extern int getopt_long (int argc, char ** argv, const char * shortopts, const struct option * longopts, int * longind); extern int getopt_long_only (int __argc, char *const *__argv, const char *__shortopts, const struct option *__longopts, int *__longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int __argc, char *const *__argv, const char *__shortopts, const struct option *__longopts, int *__longind, int __long_only); # endif #else /* not __STDC__ */ extern int getopt (); # ifndef __need_getopt extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); # endif #endif /* __STDC__ */ #ifdef __cplusplus } #endif /* Make sure we later can get all the definitions and declarations. */ #undef __need_getopt #endif /* getopt.h */ 1.9.12~dfsg/windows/JackWinEvent.cpp0000644000000000000000000001012213214314510016062 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackWinEvent.h" #include "JackTools.h" #include "JackError.h" #include // http://www.codeproject.com/win32/Win32_Event_Handling.asp // http://www.codeproject.com/threads/Synchronization.asp namespace Jack { void JackWinEvent::BuildName(const char* name, const char* server_name, char* res, int size) { snprintf(res, size, "jack_pipe.%s_%s", server_name, name); } bool JackWinEvent::Signal() { BOOL res; assert(fEvent); if (fFlush) return true; if (!(res = SetEvent(fEvent))) { jack_error("JackWinEvent::Signal name = %s err = %ld", fName, GetLastError()); } return res; } bool JackWinEvent::SignalAll() { BOOL res; assert(fEvent); if (fFlush) return true; if (!(res = SetEvent(fEvent))) { jack_error("JackWinEvent::SignalAll name = %s err = %ld", fName, GetLastError()); } return res; } bool JackWinEvent::Wait() { DWORD res; if ((res = WaitForSingleObject(fEvent, INFINITE)) == WAIT_TIMEOUT) { jack_error("JackWinEvent::TimedWait name = %s time_out", fName); } return (res == WAIT_OBJECT_0); } bool JackWinEvent::TimedWait(long usec) { DWORD res; if ((res = WaitForSingleObject(fEvent, usec / 1000)) == WAIT_TIMEOUT) { jack_error("JackWinEvent::TimedWait name = %s time_out", fName); } return (res == WAIT_OBJECT_0); } // Client side : get the published semaphore from server bool JackWinEvent::ConnectInput(const char* name, const char* server_name) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackWinEvent::Connect %s", fName); // Temporary... if (fEvent) { jack_log("Already connected name = %s", name); return true; } if ((fEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, fName)) == NULL) { jack_error("Connect: can't check in named event name = %s err = %ld", fName, GetLastError()); return false; } else { return true; } } bool JackWinEvent::Connect(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackWinEvent::ConnectOutput(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackWinEvent::Disconnect() { if (fEvent) { jack_log("JackWinEvent::Disconnect %s", fName); CloseHandle(fEvent); fEvent = NULL; return true; } else { return false; } } bool JackWinEvent::Allocate(const char* name, const char* server_name, int value) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackWinEvent::Allocate name = %s val = %ld", fName, value); /* create an auto reset event */ if ((fEvent = CreateEvent(NULL, FALSE, FALSE, fName)) == NULL) { jack_error("Allocate: can't check in named event name = %s err = %ld", fName, GetLastError()); return false; } else if (GetLastError() == ERROR_ALREADY_EXISTS) { jack_error("Allocate: named event already exist name = %s", fName); CloseHandle(fEvent); fEvent = NULL; return false; } else { return true; } } void JackWinEvent::Destroy() { if (fEvent != NULL) { jack_log("JackWinEvent::Destroy %s", fName); CloseHandle(fEvent); fEvent = NULL; } else { jack_error("JackWinEvent::Destroy synchro == NULL"); } } } // end of namespace 1.9.12~dfsg/windows/jack_dummy.cbp0000644000000000000000000001304413214314510015645 0ustar rootroot 1.9.12~dfsg/windows/Setup/0000755000000000000000000000000013214314510014132 5ustar rootroot1.9.12~dfsg/windows/Setup/src/0000755000000000000000000000000013214314510014721 5ustar rootroot1.9.12~dfsg/windows/Setup/src/COPYING0000644000000000000000000010451313214314510015760 0ustar rootroot GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . 1.9.12~dfsg/windows/Setup/src/32bits/0000755000000000000000000000000013244556535016051 5ustar rootroot1.9.12~dfsg/windows/Setup/src/32bits/JackRouter.ini0000644000000000000000000000012513214314510020577 0ustar rootroot[IO] input=4 output=4 float-sample=0 [AUTO_CONNECT] input=1 output=1 alias=01.9.12~dfsg/windows/Setup/src/logo_installer.bmp0000644000000000000000000010027213214314510020440 0ustar rootrootBMº€6(.ëÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜šŸ(,6!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,`ckÐÑÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhjr!,!,"-15?926A27A26A16@#'2!,!,&*4ÏÏÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿeho!, $/qu|ççèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÃÌÒ›£ª=BL!,,0:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,0:!,QX`¾ÃÆûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖ¶¾Å27A!,œ¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,!&1jt|¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖv|…!,cemÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,'.8kv}¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖ—Ÿ¦!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ*ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ5ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿšÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¢!,(0:lw~¾ÄÇûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíîð¿Åǘ_lsCRZAPYAPYAPYAPYLZcerz~Š’–¢©°ºÁÄÎÔÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖŸ§®!,)-8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’’’ŽŽŽ\^a *&-6bkqª¯±ßßàâââããããããâââãããâââÓÔÕ«¯²€ˆVbh>KR;=?;=?;=?;=?;=?;=?;=?;=?456ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*)-//24479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> 9ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*)-//24479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !!ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*7:<268479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !Wÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*jlm?BD479:<>;=?;=?<>@^`b~;=?;=?;=?:<> !ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%ŠŒŽ—™šCFI"$$(*jlm?BD479:<>EGI†ˆ‰ÈÈÉËÌÌcef;=?;=?;=?:<> !mÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%º»¼ÿÿÿùùùŒŽ #"$$(*jlm?BD7:<Žäå劌NPR–—˜;=?;=?;=?;=?:<> !?ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%µ¶·ÿÿÿÿÿÿùùùnqr"$$(*jlm?BD479<>@hjk®¯°ÎÏϾ¾¿RTV;=?;=?;=?:<> !rÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #% |~€ùùùÿÿÿÏÐÑ$'*$(*jlm?BD479:<>;=?;=?BDF}~‘’;=?;=?;=?:<> !.ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%!ÃÄÄÿÿÿèèè?BD$(*jlm?BD479:<>degÄÅÆÅÅÆÂÂÃpqs;=?;=?;=?:<> !$ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%±²³ÿÿÿîîîILN$(*jlm?BD479:<>;=?;=?;=?IJL¯¯°;=?;=?;=?:<> !?ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%ÂÃÄÿÿÿééé@CF$(*jlm?BD479:<>IKMlnolnoƒ…†——™;=?;=?;=?:<> !Dÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%9TVX’’‘’“’’uvx;=?;=?;=?:<> !Vÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%!6:>@B†‡ˆÈÈɽ½¾Y[\;=?;=?;=?:<> !ÿÿ"$135CDDÎÎÎøøøøøøøøø÷÷÷øøø÷÷÷øøøøøø÷÷÷÷÷÷ö÷÷öööööööööûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìììEHK"$$(*jlm?BD479:<>hik  ¡=?AY[]±²²;=?;=?;=?:<> !®ÿ"$135CDDÔÔÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿååæX[]"$$(*jlm?BD69;JLNz{}ŒŽNPRYZ\žŸ;=?;=?;=?:<> !$ÿ"$135CDDÔÔÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûáââ´µ¶npr!$'"$$(*jlm?BD=@Bœž®¯°®¯°®¯°®¯°‰ŠŒ;=?;=?;=?:<> !óÿ"$135CDDWWW\\\\\\\\\[[[\\\[[[\\\\\\XYYPQQFHI=?@368*.0"%("$$(*jlm?BD479@CE\^`klnJKMJKMEGI;=?;=?;=?:<> !ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*jlm?BD8;=kmn¶¶·¶··¶¶·Ž‘;=?;=?;=?:<> !?ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%%*,_ac"$$(*jlm?BD479:<>;=?_`b”•–}€@BC;=?;=?;=?:<> !ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%JMP¨©ªôôôÕÕÖ"$$(*jlm?BD479:<>\]_¶·¸prsŒŽœž;=?;=?;=?:<> !Lÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%'+-z}~Ö××ÿÿÿÿÿÿÿÿÿÕÕÖ"$$(*jlm?BD479:<>stvxy{;=?FHJ©ª«;=?;=?;=?:<> !ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-."&(PSU«¬®õõõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÐÐ"$$(*jlm?BD479:<>IKM¼½¾ÅÆÆËËÌpqs;=?;=?;=?:<> !žÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@AHIJ‹ŒÛÛÜþþþÿÿÿÿÿÿÿÿÿÿÿÿôôô±²³`cd"&)"$$(*jlm?BD479:<>;=?;=?ACE<>@;=?;=?;=?;=?:<> !ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLNNNyyy¾¾¾øøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóóxz|!%("$$(*jlm?BD479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !¾ÿ"$135CDDLLLLLLLLLLLLLLLLLL^^^ŸŸŸäääÿÿÿÿÿÿÿÿÿÿÿÿüüüÉÊË¡£¤ûûûèèé8;>"$$(*jlm?BD479:<><>@MOQNPR;=?;=?;=?;=?;=?:<> !ÿÿ"$135CDDLLLLLLLLLNNN}}}ÄÄÄúúúÿÿÿÿÿÿÿÿÿþþþØÙÙ=@BKOQúúúèèé8;>"$$(*jlm?BD479Y[]ÌÍÍÄÅÅÃÃÄÎÎÏY[];=?;=?;=?:<> !Dÿ"$135CDDLLL___¢¢¢çççÿÿÿÿÿÿÿÿÿÿÿÿåå妧§`aa689*-. #%KOQúúúèèé8;>"$$(*jlm?BD:=?³´µ[]_;=?;=?abd¸¸¹;=?;=?;=?:<> !>ÿ"$135NNOÃÃÃûûûÿÿÿÿÿÿÿÿÿûûû¸¸¸rrrNNNIJJ?@A567*-. #%KOQúúúèèé8;>"$$(*jlm?BD>AC´µµ<>@;=?;=?GIJ¶·¸;=?;=?;=?:<> !ÿÿ"$135LLL¬¬¬íííÿÿÿÿÿÿÿÿÿÿÿÿöööÅÅÅŒŒŒVVV?@A567*-. #%KOQúúúèèé8;>"$$(*jlm?BD69;oqrBDF;=?;=?]_`yz|;=?;=?;=?:<> !%ÿ"$135CDDLLLPPP€€€ÁÁÁøøøÿÿÿÿÿÿÿÿÿÿÿÿùùùÉÉɆ‡‡?BC #%KOQúúúèèé8;>"$$(*jlm?BD479:<>>@B|}~·¸¹ ¡¢KLN;=?;=?;=?:<> !*ÿ"$135CDDLLLLLLLLLLLLXXX’’’ÕÕÕýýýÿÿÿÿÿÿÿÿÿÿÿÿûûûÊÊË}€knpúúúèèé8;>"$$(*jlm?BD479:<>deg£¤¥MOPkln¤¥¦;=?;=?;=?:<> !?ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLfff¥¥¥åååÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëëë>AD"$$(*jlm?BD479:<>pqs…†‡;=?OQSª«¬;=?;=?;=?:<> !ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLKLLnno°°±ðððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõõ¶·¸iln$)+"$$(*jlm?BD479:<>BDF¦§¨ËÌÌÁÂÂ\]_;=?;=?;=?:<> !7ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567468lop¼½¾ùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷ø§©ª"$$(*jlm?BD479:<>QSU‡ˆ‰†ˆ‰‡ˆ‰npq;=?;=?;=?:<> !ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%,02}€ÒÓÔþþþÿÿÿÿÿÿÿÿÿÕÕÖ"$$(*jlm?BD479:<>XZ[©««yz|y{|egh;=?;=?;=?:<> !?ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%@CF–—™çççÿÿÿÕÕÖ"$$(*jlm?BD479:<>tvwƒ„…;=?;=?;=?;=?;=?;=?:<> !5ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #% X[]ŒŽ"$$(*jlm?BD479:<>HJK®®¯ÅÆÆÅÅÆ˜™š;=?;=?;=?:<> !Jÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*jlm?BD479:<>JLNoprnpropr^_a;=?;=?;=?:<> !ÿ"$135CDDLLLLLLLLLLLLLLLLLLaaa———ÀÀÀÛÜÜëììñññìììÛÛܼ½½‹ŽJMO"$$(*jlm?BD479:<>Y[]º»»‘’“‘’“vwx;=?;=?;=?:<> !?ÿ"$135CDDLLLLLLLLLLLLkkkÅÅÅûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÝÞoqs "$$(*jlm?BD479:<>tuvz{|;=?;=?;=?;=?;=?;=?:<> !ÿ"$135CDDLLLLLLNNN¢¢¢ùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃÄÅ158"$$(*jlm?BD479:<>OPR¾¿ÀÅÆÆÅÅÆ˜™›;=?;=?;=?:<> !)ÿ"$135CDDLLLOOOºººýýýÿÿÿÿÿÿÿÿÿëëë»»»˜˜˜}}~klmgijtvw•—˜ÒÒÓýýýÿÿÿÿÿÿÿÿÿÚÚÛ59;"$$(*jlm?BD479:<>;=?PRS‚ƒ…lno<>@;=?;=?;=?:<> !ÿ"$135CDDLLL¦¦¦ýýýÿÿÿÿÿÿÜÜÜ‚‚‚OOOLLLIJJ?@A567*-. #%CFH¼½¾þþþÿÿÿÿÿÿÂÃÄ$(*"$$(*jlm?BD479:<>TVX¼½¾¿¿À¥¥¦’“”;=?;=?;=?:<> !¼ÿ"$135CDDlllöööÿÿÿÿÿÿ´´´SSSLLLLLLLLLIJJ?@A567*-. #%†ˆŠûûûÿÿÿûûûnqr"$$(*jlm?BD479:<>tvw{|~˜™šDFH©ª«;=?;=?;=?:<> !ÿÿ"$135CDDµµµÿÿÿÿÿÿ¿¿¿QQQLLLLLLLLLLLLIJJ?@A567*-. #%œŸÿÿÿÿÿÿÄÅÅ#&$(*jlm?BD479:<>TVWÄÄų´´GIK‰Š‹;=?;=?;=?:<> !Fÿ"$135EEEèèèÿÿÿ÷÷÷eeeLLLLLLLLLLLLLLLIJJ?@A567*-. #%47:æççÿÿÿååæ9=?$(*jlm?BD479:<>;=?QSU‹ŒVXZ;=?;=?;=?;=?:<> !-ÿ"$135WWXöööÿÿÿÏÏÏRRRLLLLLLLLLLLLLLLIJJ?@A567*-. #%»½½ÿÿÿðððMPR$(*jlm?BD479:<>NPQÇÇÈ›œ¶¶·†‡ˆ;=?;=?;=?:<> !7ÿ"$135dddøøøÿÿÿ¼¼¼MMMLLLLLLLLLLLLLLLIJJ?@A567*-. #%Ÿ¡¢ÿÿÿôôôSVX$(*jlm?BD479:<>vxyxy{;=?EGIª«¬;=?;=?;=?:<> !ÿÿ"$135ccdøøøÿÿÿ¿¿¿NNNLLLLLLLLLLLLLLLIJJ?@A567*-. #%£¥¦ÿÿÿñññNQS$(*jlm?BD479:<>[\^xz{;=?JKM—˜™;=?;=?;=?:<> !,ÿ"$135WXXöööÿÿÿÊÊÊQQQLLLLLLLLLLLLLLLIJJ?@A567*-. #% ÂÃÄÿÿÿæææ;?A$(*jlm?BD479;>@^`a`acGHKCEG;=?;=?;=?;=?:<> !dÿ"$135FFGîîîÿÿÿäääWWWLLLLLLLLLLLLLLLIJJ?@A567*-. #%?BEïïïÿÿÿËÌÌ!%($(*jlm?BD479\^`ËÌÍÌÍι¹ºÁžŸ ;=?;=?;=?:<> !Öÿ"$135CDDÊÊÊÿÿÿþþþwwwLLLLLLLLLLLLLLLIJJ?@A567*-. #%"°²²ÿÿÿþþþ|€"$$(*jlm?BD479:<>abdcef;=?DFH¢£¤;=?;=?;=?:<> !ÿÿ"$135CDDýýýââↆ†LLLLLLLLLLLLLLLIJJ?@A567*-. #%‰‹þþþÿÿÿØÙÙ-13"$$(*jlm?BD479;=?WY[\^_;=?;=?;=?;=?;=?;=?:<> !ÿÿ"$135CDDSSSrrrNNNLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%!%(œžŸîîïY\]"$$(*jlm?BD8;=“•–prsÅÅÆÅÅÆÅÅŘ™š;=?;=?;=?:<> !Íÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%-13"$$(*jlm?BD479:<>;=?TUW…†‡npq<>@;=?;=?;=?:<> !Öÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*jlm?BD479:<>XZ[½½¾€ƒš›œ–˜™;=?;=?;=?:<> !ÿÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*jlm?BD479:<>suvuvx;=?EGH§¨©;=?;=?;=?:<> !ÿÿ"$135CDD[[[````````````````````````]^^TUVKLMBDE8;=046-14-14-14-14-14-14.24.14"$$(*jlm?BD479:<>MOQÂÂö·¸ÆÆÇz{};=?;=?;=?:<> !ÿÿ"$135CDDÔÔÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÕÖ"$$(*jlm?BD479:<>BDFUWYhik[\^LMO;=?;=?;=?:<> !½ÿ"$135CDDÔÔÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÕÖ"$$(*jlm?BD479:<>\]_ÌÌͬ­®¬­®ˆ‰Š;=?;=?;=?:<> !ÿÿ"$135CDDËËËóóóóóóóóóóóóóóóóóóóóóóóóóóóòòòòòòùùùÿÿÿÿÿÿÿÿÿúúúðððððððððððððððÈÉÊ"$$(*jlm?BD479:<>qstwxz;=?;=?;=?;=?;=?;=?:<> !ÿÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJBCC„„…îîïÿÿÿÿÿÿÁÂÃ6:<"$$(*jlm?BD479:<>WYZËËÌÅÆÇÅÅÆ˜š›;=?;=?;=?:<> !ÿÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLL^__ÄÄÄýýýÿÿÿõõõƒ…†!"$$(*jlm?BD479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !~ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLMMMŒŒŒîîîÿÿÿÿÿÿרØNPR"$$(*jlm?BD479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !ÿÿ"$135CDDLLLLLLLLLLLLLLLLLL]]]ÂÂÂýýýÿÿÿÿÿÿÿÿÿîîî~€!#"$$(*jlm?BD479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !ÿÿ"$135CDDLLLLLLLLLLLLLLL‡‡‡ìììÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍÎÏKNP"$$(*jlm?BD9<>›œžÂÃÄÂÂÄÂÃÄÂÂÄ—˜™;=?;=?;=?:<> !õÿ"$135CDDLLLLLLLLLZZZ¾¾¾üüüÿÿÿÿÿÿììì„„„uvvÚÚÚÿÿÿÿÿÿÿÿÿùùù¢£¥)-0"$$(*jlm?BD58:?BDHJLŸ  ¯¯°HJL@BD;=?;=?;=?:<> !Yÿ"$135CDDLLLLLLêêêÿÿÿÿÿÿþþþÄÄÄ___IJJ?@A<>?‰‹Œïïïÿÿÿÿÿÿÿÿÿééépsu"$$(*jlm?BD479Z\^¿¿À•–—ÆÇÇ‘’?AC;=?;=?;=?:<> !Fÿ"$135CDDWWW¸¸¸üüüÿÿÿÿÿÿñññŽŽŽOOOLLLIJJ?@A567*-.9<>ª¬­úúúÿÿÿÿÿÿÿÿÿÈÉÉFIK"$$(*jlm?BD:<>ŒŽPRT;=?>@BˆŠ‹¢£¤;=?;=?;=?:<> !ÿÿ"$135CDDÌÌÌÿÿÿÿÿÿÿÿÿÍÍÍcccLLLLLLLLLIJJ?@A567*-. #%NQTÏÐÐÿÿÿÿÿÿÿÿÿøøøœžŸ+/1"$$(*jlm?BD58:]_anpqš›œyz|xz|fhj;=?;=?;=?:<> !Gÿ"$135CDDÔÔÔÿÿÿõõõ———PPPLLLLLLLLLLLLIJJ?@A567*-. #%!wy{ëììÿÿÿÿÿÿÿÿÿËÌÍ"$$(*jlm?BD7: !Yÿ"$135CDDÔÔÔÕÕÕhhhLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%+/2¤¥§úúúÿÿÿÕÕÖ"$$(*jlm?BD479ACE‚‚„hjkcef@BD;=?;=?;=?:<> !Âÿ"$135CDDPPPLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%JMOËÌÍÕÕÖ"$$(*jlm?BD479WYZ³´µµ¶¶˜™š£¤¥¬­®;=?;=?;=?:<> !ÿÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%!VY["$$(*jlm?BD479:<>WY[Y[];=?BDF‘;=?;=?;=?:<> !©ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*jlm?BD479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !–ÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*@CE48:479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !Öÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*)-//24479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> !ÿÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*)-//24479:<>;=?;=?;=?;=?;=?;=?;=?;=?:<> ÿÿ"$135CDDLLLLLLLLLLLLLLLLLLLLLLLLLLLIJJ?@A567*-. #%"$$(*)-//24479:<>;=?;=?;=?;=?;=?;=?;=?;=?456ùÿVVV"##''')))))))))))))))))))))))))))())&&&##$ !! !!!"##$$$%&%%&%%&%%&%%&%%&$%&%%&$$%VVVÔÿÿÿÿYYYYYYÿÿÿÿÿÿÿÿÿÿÿÊÊÊŽŽŽ[\` )!+NSZµ·¹ÞÞÞßßßßßßßßßßßßßßßßßßØØØµ¹ºŽ•˜hqwEQX16@27A26A27A05? $/!,!,ehoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•—œ&*4!,!,!,#- $. $. $. $/ $/ $/#."-"-"-"-"-"-"-"-#.#.#.#.#.#.!,!,!,!,!,hjrÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿžÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£¥©!,4>G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78G—Ÿ¤ôõõÿÿÿÿÿÿÿÿÿÿÿÿøùùÆË͆–M[dAPYAPYAPYJXaiv~‹—ž­·½ÅÎÔÇÐÖÇÐÖÇÐÖ³¼Â(-78;=?;=?;=?69< *8;=?;=?;=?69< *8;=?;=?;=?69< *8;=?;=?;=?69< *8G!,LU^ÚÝßÿÿÿÿÿÿÿÿÿÓÖØu€†BQZAPYGV_r‡¦°·ÅÎÔÇÐÖŒ”›!,CENÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;>G!,LU^ÚÝßÿÿÿÿÿÿÿÿÿÓÖØu€†BQZAPYGV_r‡¦°·ÅÎÔÇÐÖŒ”›!,CENÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿBÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;>G!,LU^ÚÝßÿÿÿÿÿÿÿÿÿÓÖØu€†BQZAPYGV_r‡¦°·ÅÎÔÇÐÖŒ”›!,CENÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;>G!,LU^ÚÝßÿÿÿÿÿÿÿÿÿÓÖØu€†BQZAPYGV_r‡¦°·ÅÎÔÇÐÖŒ”›!,CENÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;>G!,LU^ÚÝßÿÿÿÿÿÿÿÿÿÓÖØu€†BQZAPYGV_r‡¦°·ÅÎÔÇÐÖŒ”›!,CENÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿHÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;>G!,LU^ÚÝßÿÿÿÿÿÿÿÿÿÓÖØu€†BQZAPYGV_r‡¦°·ÅÎÔÇÐÖŒ”›!,CENÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;>G!,LU^ÚÝßÿÿÿÿÿÿÿÿÿÓÖØu€†BQZAPYGV_r‡¦°·ÅÎÔÇÐÖŒ”›!,CENÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿory!,!,!,).8LOXUXaUX`UXaJNW28B&-7&-7'.828B?DNGLVGMV9=H!,!,!,fipÖ×Ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ37A!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,,0:ÕÖØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£¥©!,$/3>Hv…ÑÒÕâãåããåâãåããåâãåããäÇÉÌhryHV_¤«°ùúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôôõ’šŸET]BQZfs|©´»ÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖÇÐÖ­µ¼!%08" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "DirectSound", or "ASIO". Alternatively using the following command allows to display the names of available devices: - jackd -d portaudio -l to display the entire list of available audio devices. (jackd -d portaudio -h will display all portaudio driver features) Then start jackd with the device you want, by using its name, for example: - jackd -R -S -d portaudio -d "ASIO::MOTU Audio ASIO", then start QJACKCTL. QJACKCTL will see the jackd server already running and then can be used normally. ============================================= Jack MIDI ============================================= A first version of a JACK MIDI <==> Windows MIDI bridge (using Windows MME API) is available. If can be activated using the -X parameter in jackd command line. So add "-X winmme" in QJACKCTL settings (something like "jackd -S -X winmme"). The WinMME driver will scan MIDI input/output ports, open corresponding JACK MIDI ports and convert MIDI in/out into JACK MIDI messages. QJACKCTL MIDI connection windows can then be used. ============================================= JackRouter JACK/ASIO driver ============================================= JackRouter is an ASIO driver that allows any ASIO compatible application to become a JACK client, thus exchange audio with any other "native" or "Jackified" application. This driver is registered in the system by the installer and becomes available in the list of ASIO drivers when the JACK server is running. A "JackRouter.ini" configuration file allows the application to configure how the JackRouter driver behaves. - [IO]: - input/output : the application can obtain any number if JACK input/output ports (not necessarily equal to the audio card input/output number). [Note that some applications force their input/output channel number]. - float-sample : be default the JackRouter will present audio samples in integer format for the application. Use float-sample=1 so that audio samples are presented in float format for the application (thus saving float/integer conversion time). - [AUTO_CONNECT] : - input/output : when 1, the application JACK port will automatically be connected to the machine input/output JACK ports. - alias : with ASIO drivers, real channels names will be associated to the JACK port as aliases and will be returned when the application request channels names. ============================================= Known problems ============================================= - starting/stopping the server several times in QJACKCTL may not work correctly. You may have to quit QJACKCTL and launch it again. ============================================= Grame : Computer Music Research Laboratory Web : http://www.grame.fr/Research E-mail : letz@grame.fr =============================================1.9.12~dfsg/windows/Setup/src/gpl_installer.rtf0000644000000000000000000000175113214314510020301 0ustar rootroot{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Courier New;}} {\colortbl ;\red0\green0\blue255;} {\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\lang1036\f0\fs20 Copyright (C) 2001 Paul Davis\par Copyright (C) 2004-2014 Grame\par \par This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or\par (at your option) any later version.\par \par This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\par GNU General Public License for more details.\par \par You should have received a copy of the GNU General Public License along with this program. If not, see <{\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/"}}{\fldrslt{\ul\cf1 http://www.gnu.org/licenses/}}}\f0\fs20 >.\par } 1.9.12~dfsg/windows/Setup/src/64bits/0000755000000000000000000000000013244556535016056 5ustar rootroot1.9.12~dfsg/windows/Setup/src/64bits/JackRouter.ini0000644000000000000000000000012713214314510020606 0ustar rootroot[IO] input=4 output=4 float-sample=0 [AUTO_CONNECT] input=1 output=1 alias=0 1.9.12~dfsg/windows/Setup/src/jack.ico0000644000000000000000000007572613214314510016346 0ustar rootroot@@ (Bf@@(ŽB  ¨¶X ¨^i hrhnv(@€ €ÿ ÿ%'&ÿÿ ÿ_b`ÿA?;ÿ')(ÿFHGÿÿ@BAÿäàâÿŠ‹ÿ576ÿ')(ÿLHJÿÿA?;ÿÂÃÈÿäàâÿ”’ÿA?;ÿ')(ÿA?;ÿ ÿÿZ][ÿÆÉÇÿäàâÿ”’ÿ;=;ÿ+-+ÿ8:9ÿÿÿÿÿZ][ÿÂÃÈÿäàâÿ”’ÿ')(ÿ)=HÿCcsÿ" ÿÿÿÿZ][ÿÃÆÄÿµ¸¶ÿ/?IÿF`oÿNo€ÿEeuÿ"$ÿ ÿ ÿÿZ][ÿW]dÿf}‹ÿF`oÿF`oÿNo€ÿEeuÿ"$ÿÿ ÿÿ‹–§ÿŽž²ÿf}‹ÿB\kÿF`oÿNo€ÿEeuÿ"$ÿÿ ÿÿÿÿÿÿÀËÝÿ¤µÉÿŽž²ÿf}‹ÿF`oÿF`oÿNo€ÿF`oÿ"$ÿ ÿÿ?Aÿf€ÿc”ÿMsÿ/ÿÿÿ…ÿÀËÝÿ¤µÉÿŽž²ÿf}‹ÿB\kÿF`oÿNo€ÿ9Saÿ ÿÿ~ÿßöÿ¹ñÿu²ÿHmÿÿÿÿ…Š˜ÿÀËÝÿ¤µÉÿŽž²ÿf}‹ÿB\kÿ4HTÿÿ ÿ ÿÿILÿ‹”ÿ™ÅÿƒÃÿ\Œÿ"3ÿÿÿ…Š˜ÿÀËÝÿ¤µÉÿŽž²ÿO`kÿ%'&ÿÿÿÿ ÿ&(ÿ~ÿßöÿÀúÿ”Þÿc”ÿ"3ÿÿÿ…‹“ÿÀËÝÿŽž²ÿuxvÿƒ€{ÿ<=Bÿ ÿ ÿÿ ÿ!"ÿ~ŠÿßöÿÀúÿ”Þÿj¤ÿ"3ÿÿÿ…‹“ÿwzxÿûÿýÿÂÃÈÿA?;ÿ<=Bÿÿÿÿ ÿ!"ÿ~ÿßöÿÀúÿ”Þÿc”ÿ"3ÿÿ ÿÁÏÓÿûÿýÿ”’ÿÂÃÈÿplnÿA?;ÿÿ ÿÿ ÿ!"ÿyÿßöÿÀúÿ”Þÿj¤ÿ"3ÿÿ*FHÿÄõ÷ÿ¯¾ÂÿÃÆÄÿûÿýÿÏÒÐÿtz‚ÿA?;ÿÿ ÿÿ ÿ!"ÿ~ÿßöÿÀúÿ”Þÿc”ÿ"3ÿÿÿ Žÿmééÿnˆ‰ÿôýþÿûÿýÿûÿýÿÏÒÐÿƒ€{ÿA?;ÿÿ ÿÿ ÿ!"ÿyÿßöÿÀúÿ”Þÿg¡ÿ"3ÿÿÿ¢­ÿœ ÿ_»»ÿÄõ÷ÿëûÿÿûÿýÿøöðÿÒÕÓÿtz‚ÿA?;ÿÿÿ ÿ ÿ!"ÿ~ÿßöÿÀúÿ”Þÿc”ÿ"3ÿÿÿŒ ÿbnÿÏÔÿmééÿÄõ÷ÿôýþÿûÿýÿûÿýÿÒÕÓÿplnÿ<=Bÿÿÿÿ ÿ&(ÿ~ÿßöÿÀúÿ”Þÿg¡ÿ"3ÿÿÿWfÿ T_ÿ®¼ÿÏÔÿmééÿÄõ÷ÿôýþÿûÿýÿûÿýÿÏÒÐÿƒ€{ÿA?;ÿÿÿÿ ÿ!"ÿ~ÿßöÿÀúÿ”Þÿc”ÿ*>ÿÿ ÿÿ>‡ÿ:ÀÎÿ ™¼ÿ/‹¶ÿ/j‡ÿ&/ÿÿ ÿaxÿ‰œÿ®¼ÿ<àåÿmééÿÄõ÷ÿŽ‘ÿûÿýÿøöðÿge`ÿ‚‡ÿLHJÿFHGÿ697ÿ+-+ÿ=DDÿ-@>ÿZ]ÿvzÿhŽÿMsÿ-Aÿ ÿÿ ÿaxÿ‰œÿ®¼ÿÏÔÿ>‡ÿµßÞÿëûÿÿ…‹“ÿµ¸¶ÿ¦©§ÿ‚‡ÿLHJÿLHJÿ576ÿ%'&ÿÿ&(ÿÍÚÿ²öÿg¡ÿ-Aÿ ÿ ÿ ÿdvÿÿ®¼ÿ wÿmééÿœÅÄÿŽ‘ÿÒÕÓÿÂÃÈÿ¦©§ÿ‚‡ÿFHGÿ132ÿÿÿÿ¶¿ÿ­ïÿ\Œÿ!ÿ+ÿ"3ÿÿaxÿ}”ÿvzÿÏÔÿ;ywÿªÆÇÿºÂÃÿÔ×ÕÿÂÃÈÿ¦©§ÿplnÿ)*.ÿÿ ÿÿyÿc”ÿ*>ÿÿEjÿ-Fÿ ÿI[ÿtƒÿ™©ÿ jjÿ|ÅÇÿªÆÇÿºÂÃÿÔ×Õÿ¨«©ÿ‚‡ÿ”’ÿLHJÿÿÿge`ÿÔ×Õÿ‚‡ÿ%1ÿ}»ÿ+ÿÿWfÿbnÿ3Œÿ2¢¥ÿ|ÅÇÿªÆÇÿ½Á¾ÿ|}ÿûÿýÿïóñÿ¢¥£ÿÿÿÿƒ€{ÿÙÜÚÿ‚‡ÿ[rÿÿ ÿ4=ÿ>‡ÿ;›¡ÿ2¢¥ÿ|ÅÇÿrŒÿÁÏÓÿôýþÿûÿýÿ”’ÿµ¸¶ÿA?;ÿÿÿ‚‡ÿäàâÿy|zÿ ÿÿ3_lÿ?‡•ÿ<•™ÿ2¢¥ÿSÿ¼õñÿÄõ÷ÿ¶Ú×ÿ¢¥£ÿøöðÿÂÃÈÿA?;ÿÿ ÿƒ€{ÿäàâÿtz‚ÿ ÿ ÿ3_lÿ>‡ÿ3Œÿ;›¡ÿHâçÿHâçÿ&†‹ÿÁÄÂÿøöðÿøöðÿÂÃÈÿA?;ÿ ÿÿƒ†„ÿÙÜÚÿƒ€{ÿÿ ÿ3_lÿ2`gÿ¶¿ÿÃÍÿ»ÄÿtƒÿjmkÿÂÃÈÿèëéÿó÷ôÿÂÃÈÿ<=Bÿÿÿ‚‡ÿÙÜÚÿƒ€{ÿÿ ÿ%4ÿ®¼ÿ¢­ÿ™©ÿ‰œÿ?JÿplnÿÏÒÐÿèëéÿøöðÿÂÃÈÿA?;ÿÿÿƒ€{ÿäàâÿtz‚ÿ ÿÿ{†ÿŠžÿ}”ÿm‡ÿ%Ytÿ)8ÿplnÿÂÃÈÿøöðÿïóñÿÂÃÈÿA?;ÿÿÿ‚‡ÿÙÜÚÿ‚‡ÿ ÿÿP_ÿQdÿÿ%4ÿ)8ÿ4=ÿ1<ÿ%'&ÿ')(ÿ(+)ÿ+-+ÿ)*.ÿ132ÿ576ÿ697ÿ8:9ÿ;=;ÿA?;ÿ-@>ÿ-Aÿ-Fÿ?Aÿ‡ÿ?‡•ÿ3Œÿ<•™ÿŒ ÿœ ÿ™©ÿ;›¡ÿ/‹¶ÿ ™¼ÿ¢­ÿ¤°ÿ®¼ÿ¶¿ÿ2¢¥ÿnˆ‰ÿ‚€ÿ…ÿrŒÿ_»»ÿƒÃÿ™Åÿ”Þÿ»Äÿ­ïÿ²öÿ¹ñÿÃÍÿÍÚÿÏÔÿ:ÀÎÿÀúÿßöÿ<àåÿ|ÅÇÿHâçÿmééÿ‚‡ÿƒ†„ÿŠ‹ÿŽ‘ÿ…‹“ÿ…Š˜ÿ”’ÿ˜›šÿ‹–§ÿŽž²ÿ¢¥£ÿ¦©§ÿ¨«©ÿµ¸¶ÿ½Á¾ÿ¯¾Âÿ¤µÉÿœÅÄÿªÆÇÿºÂÃÿ¶Ú×ÿµßÞÿ¿ðñÿ¼õñÿÁÄÂÿÃÆÄÿÅÈÆÿÆÉÇÿÂÃÈÿÈËÉÿÊÎËÿÁÏÓÿÀËÝÿÏÒÐÿÒÕÓÿÔ×ÕÿÙÜÚÿÝàÞÿÄõ÷ÿäàâÿèëéÿïóñÿëûÿÿó÷ôÿøöðÿôýþÿûÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿh1(^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\á¼-(_ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ1ÖáÀ1(1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿcÕáÀ0*/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿcÖáÀ(:iÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿcÓÇ;f‹jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿceŒff‹jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂÃŒdf‹jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÊÃŒff‹f5z‚Jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¦ÚÊÃŒdf‹MWµ¯‰Gÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÚÊÃŒdE>ª©y ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÚÊÃg'Wµ´«‚ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾ÚÃsw<µ´«ˆ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾tèÖ1<Wµ´«‚ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙèÀÖp1 Vµ´«ˆ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿCàÉÓèÛ1Wµ´«‚ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ޹¤çèèÛw1Vµ´«‡ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸš¨àäèæÜ1Wµ´«‚ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™Q²¹àçèèÜp< Wµ´«‡ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿI@¡²¹àçèèÛw1Wµ´«‚"ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ6“¡²¹àäèæÛ<Vµ´«‡ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ R“¡¶¹àçèèáp1Vµ´«‚ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿR’Ÿ²¹ÐçèæØr1W¡ƒx=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ S’¡²¹àäèæá< Pµ´«‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿS“¡²¹àçèèØw1T{L8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ S’¡¶¹ÐäèèÛt [³ž†&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿQ“¡²¹àçèæwp/+]:[³ž†&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ S’ ²¹àäÖÖÖp)_-+]2•³ž…ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿS“¡¶¹à½èæmº_^.*D2BU|J3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ S“¡²•Ïä¾Çź__-' ±®‡3 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿR’¡~¹Ë½ÜÖź^,¢­y ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ S„U²ZÌÍÝÖÅp+V‚"F4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?€›X·ÌÍÝÆºÀ_mݺ!ŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIQ—£·ÌÈvèãÄwÞºKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%•œ£·§ÙçèÀÇ1ºáuÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿN–˜£kÑàÎÄæÖ1 wáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿN•—œ¸¸”ÒææÖ1»ÞwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿNY¢°¬€nÖâåÖ<ºÞwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ#¡Ÿ›“7pÛâæÖ1wáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‘„}O$pÖæãÖ1ºÞºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ AH9#nÕâæÖ1 wáwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_ÿÿpÖæãÖ<»Þºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿn×âæÖ1wáwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖæåÖ<ºßºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿn×âæÖ1 spÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÕâæÒ<smÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿoÖææp¥áºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿqÖÖ+_<ºÝvÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpmºâÖ1m1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿsææÖ<mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿbÖâæ_ Ö^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿrÔÇ,c_ aÁ_ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpewãÞbÀ<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºâæám+w+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpáææâel^_ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ`ÀÖáæsmÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_.nÄ_ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿàÿÿÿÿÿÿà?ÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿüÿÿÿÿÿþÿÿÿÿÿþÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÀÿÿÿÿÿàÿÿÿÿÿðÿÿÿÿÿðÿÿÿÿÿàÿÿÿÿà?ÿÿÿÿàÿÿÿÿàÿÿÿÿðÿÿÿÿøÿÿÿÿüÿÿÿÿþÿÿÿÿÿÿÿÿÿ€?ÿÿÿÿÀÿÿÿÿàÿÿÿÿðÿÿÿÿøÿÿÿÿüÿÿÿÿþÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÀÿÿÿÿÿàÿÿÿÿÿðÿÿÿÿÿøÿÿÿÿÿüÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿ†ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÀÿÿÿÿÿÿàÿÿÿÿÿÿðÿÿÿÿÿø?ÿÿÿÿÿüÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÀÿÿÿÿÿÿàÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿþÿÿÿÿÿÿÿÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( @  €  €€„„‚ÿ243ÿ¿€²²³ÿ“ÿ452ÿ¿€¿±²²ÿhlnÿ@\kÿ$.3ÿ ¿¿v„’ÿMfuÿJiyÿ".4ÿ ¿ @€@€©´ÄÿŠœ®ÿMfuÿJhxÿ#&ÿ8;ÿ˜¿ÿJpÿ ¿"%(¿ªµÇÿŠœ®ÿ;KTÿ ÿ ÿ^bÿ¯Þÿ]Œÿ ¿"&&¿“œ§ÿ­¯®ÿ100ÿ ÿÿˆÿ½òÿa’ÿ ¿o……ÿÀÅÅÿ¿ÀÁÿABCÿ ÿÿ~…ÿ½òÿa’ÿ ¿€#­±ÿ¡ÍÎÿ÷þþÿÇÇÄÿCDDÿ ÿÿ~…ÿ½òÿ`’ÿ ¿€fuÿ)ÍÓÿºôõÿùÿýÿÃÅÄÿDCCÿ ÿÿ€…ÿ½òÿ`’ÿ ¿ ¿‰›ÿ1ÒØÿ¸ôöÿùüúÿÉËÌÿA@Aÿ ÿÿ}†ÿ½òÿ`’ÿ ¿ "(¿ˆ˜ÿ)ÍÓÿ¹óôÿöüúÿÆÆÄÿACEÿ ÿÿhlÿ™ÁÿR~ÿ ¿ !(¿Š›ÿ1ÒØÿ¹óôÿ÷þþÿÆÈÅÿ::9ÿ ÿÿfkÿ† ÿ"Xrÿ ¿ !%¿Š›ÿ(ËÐÿºôõÿèííÿžžÿ989ÿ/01ÿ6=@ÿ6†ÿ*Ÿ¿ÿ+f‚ÿ ¿ !(¿ˆ›ÿ1ÒØÿ‘»½ÿÙßàÿ‘’‘ÿXWYÿ999ÿ(//ÿ qvÿt¦ÿ)ÿ € "(¿‡™ÿ&©®ÿ„¥¤ÿÉÌÍÿ¤¦§ÿDDEÿÿW]ÿf“ÿ"4ÿ!€ ¿r€ÿ@—šÿ£ÅÆÿ­±®ÿÀÁÂÿHGHÿÿ¬­¬ÿ"`yÿ € ¿;‚ŒÿG¨«ÿ‘´´ÿÚóòÿ¹¹·ÿRRSÿ(()ÿ±¯®ÿ%%$¿!!¿6u}ÿ!¾Åÿ"¦®ÿ¹»¹ÿåçåÿSRRÿ+++ÿ®¯®ÿ)))¿ ¿•£ÿƒ˜ÿ2KYÿº»¼ÿèéæÿRRSÿ,,,ÿ­®±ÿ%(%¿ ¿ $-ÿ %¿"$"¿¸¹ºÿèéæÿSRRÿ*+*ÿ±±¯ÿ%&)¿"$"¿¹¹ºÿéêçÿSRRÿ-,+ÿ±±±ÿ(&%¿"$"¿º»ºÿççäÿSRPÿ!##ÿFEEÿ¿"%$¿»»¼ÿ•”•ÿ%%$ÿ+.,ÿ¯¯±ÿ&)(¿!$"¿\\\ÿççäÿSRRÿÿ531ÿ ¿¿¸ººÿ‹Š‰ÿ/..ÿKMOÿDEEÿ@%%%¿\]_ÿêìéÿmkjÿ_^_ÿ € ! ¿¯­¬ÿâááÿ‰Œ‹ÿ>><ÿ@€VWVÿ¿ÿÿÿÿÏÿÿÿ‡ÿÿÿÿÿÿÀÿÿÿà_ÿÿàÿÿðÿÿøÿÿüÿÿøÿø?ÿüÿþÿÿÿÿ€ÿÿÀÿÿàÿÿðÿÿøÿÿüÿÿþÿÿ?ÿÿðÿÿøÿÿüÿÿþÿÿÿÿÿÿÿÿÿÁÿÿÿñÿÿÿÿ( @ÿÿÿÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿÿ ÿÿ ÿÿÿÿÿ ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿ!ÿ ÿ ÿ)ÿ !%ÿ !(ÿ $-ÿ!!ÿ#&ÿ %ÿ"4ÿ8;ÿ ! ÿ!##ÿ!$!ÿ!%$ÿ%%$ÿ(%%ÿ%(%ÿ!%(ÿ%%)ÿ%)(ÿ(()ÿ)))ÿ*+*ÿ+++ÿ-,+ÿ(//ÿ+.,ÿ,,,ÿ/..ÿ$.3ÿ".4ÿ/01ÿ100ÿ531ÿ243ÿ452ÿ989ÿ::9ÿ>><ÿ6=@ÿW]ÿ;KTÿ2KYÿ^bÿJpÿR~ÿ"Xrÿhlÿfkÿfuÿ qvÿ"`yÿ6u}ÿA@AÿABCÿDCCÿACEÿCDDÿDDEÿFEEÿHGHÿKMOÿRRSÿSRQÿVWVÿXWYÿ\\]ÿ_^_ÿ@\kÿMfuÿJhxÿmkjÿhlnÿ]Œÿ}†ÿ~…ÿˆÿr€ÿ`’ÿf“ÿ+f‚ÿt¦ÿ€…ÿ‡™ÿƒ˜ÿ‰›ÿˆ›ÿˆ˜ÿŠ›ÿ6†ÿ;‚Œÿ† ÿ•£ÿ˜¿ÿ*Ÿ¿ÿ"¦®ÿ&©®ÿ#­±ÿ@—šÿo……ÿv„’ÿG¨«ÿ™Áÿ¯Þÿ!¾Åÿ½òÿ(ËÐÿ)ÍÓÿ1ÒØÿ„„‚ÿ‹Š‰ÿ‰Œ‹ÿ“ÿ‘’‘ÿ•”•ÿžžÿŠœ®ÿ“œ§ÿ„¥¤ÿ‘´´ÿ‘»½ÿ¤¦§ÿ¬­¬ÿ¯­¬ÿ­¯®ÿ®¯®ÿ±¯®ÿ­±®ÿ±±¯ÿ­®±ÿ¯¯±ÿ±±±ÿ±²²ÿ²²³ÿ¹¹·ÿ¸¹ºÿ¹¹ºÿ¸ººÿ¹»¹ÿº»ºÿº»¼ÿ»»¼ÿ©´ÄÿªµÇÿ£ÅÆÿ¡ÍÎÿ¿ÀÁÿ¹óôÿ¸ôöÿºôõÿÀÁÂÿÀÅÅÿÃÅÄÿÆÆÄÿÇÇÄÿÆÈÅÿÉËÌÿÉÌÍÿÙßàÿÚóòÿâááÿåçåÿççäÿèéæÿéêçÿêìéÿèííÿöüúÿ÷þþÿùüúÿùÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ&œQ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$´ŸR#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(³wsLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ*“tuM ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½£tu58Œ[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@¾£X Z–xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<¤«O{˜} ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’ÆÁe z˜}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ×Éhz˜}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ`šÄÙÇf˜}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ"„›ÃØËdy˜}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2†šÂÖÈg^•\ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2‡›Â×ÊT_Š] ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ1‡™ÄÕ¢SNVˆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2…›§Í pSHa€0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2‚¥Ì¨iW~7-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ/|‘¿®Åk,©b ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!‰”¦ÎµmC­=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ4c—޹ÐnF¬Dÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ‹ƒY»ÒmJ°?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ.36;¶ÒnE¯Aÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;·ÓnG²>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;ºÑn:j+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<¼¡=I±Bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;qÑn,Pÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ)¸Kli'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ=qÔvrÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ9ªÏžUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'#o%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÿÿ‡ÿÿÿÿÿÿÀÿÿÿà_ÿÿàÿÿðÿÿøÿÿüÿÿøÿø?ÿüÿþÿÿÿÿ€ÿÿÀÿÿàÿÿðÿÿøÿÿüÿÿþÿÿ?ÿÿðÿÿøÿÿüÿÿþÿÿÿÿÿÿÿÿÿÁÿÿÿñÿÿÿÿ(   @@~~ÿŸ 9<;Ÿ[lxÿ'49ï @ 0 €Š—ïWm|ÿ ÿ|œÿ +Ÿ0œ¥¨ÿPPPÿ*,ÿ–¿ÿ!.Ÿ@@«²ÿÜîíÿVVUÿ*,ÿ–¿ÿ!.Ÿ 39ŸJÇÎÿÜííÿTUUÿ*-ÿ‡¬ÿ)Ÿ 6;ŸJÆÎÿØêéÿGFFÿ 9;ÿ(€–ÿ#)Ÿ 6<Ÿ?¯·ÿ­¹¸ÿ^^_ÿADÿFeÿ@ +0ŸY¡¦ÿ¶ÆÆÿ\\\ÿjyÿ P+.ŸŸ¬ÿ£ª­ÿnnmÿkklï0 p`ž žïnnmÿlllï00ž žïKKKÿNPPï00…†…ïKJIÿ343ï0…†…ïŽÿ``  0ÿÿŸÿÿÁÿàÿàà?ðøüþÿÇÿãÿñÿùÿÿ( ÿÿÿ ÿ ÿÿ  ÿÿ ÿ ÿ ÿÿÿÿÿ)ÿ +ÿ!.ÿ*,ÿ*,ÿ#)ÿ+.ÿ +0ÿ 39ÿ 6;ÿ'48ÿ 9;ÿ343ÿ9;;ÿADÿFeÿGFFÿKJJÿMPPÿPPPÿTUUÿVVUÿ\\\ÿ^^_ÿWm|ÿ[lxÿjjkÿkkkÿnnmÿjyÿ~~ÿ|œÿ(€–ÿ‡¬ÿŸ¬ÿ–¿ÿ?¯·ÿY¡¦ÿ@«²ÿJÆÎÿ…†…ÿŽÿ€‰—ÿ ÿœ¥¨ÿ£ª­ÿ­¹¸ÿ¶ÆÆÿØêéÿÜííÿÜîíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ- ÿÿÿÿÿÿÿÿÿÿÿÿÿ(ÿÿÿÿÿÿÿÿÿÿÿ9' .ÿÿÿÿÿÿÿÿÿÿÿ;"2ÿÿÿÿÿÿÿÿÿÿ5A$2ÿÿÿÿÿÿÿÿÿÿ6@#0ÿÿÿÿÿÿÿÿÿÿ6?/ÿÿÿÿÿÿÿÿÿÿ3=&ÿÿÿÿÿÿÿÿÿÿ4>%,ÿÿÿÿÿÿÿÿÿÿÿ1<+)ÿÿÿÿÿÿÿÿÿÿÿ :+*ÿÿÿÿÿÿÿÿÿÿÿÿ: !ÿÿÿÿÿÿÿÿÿÿÿÿ7 ÿÿÿÿÿÿÿÿÿÿÿÿ78 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸÿÿÁÿàÿàà?ðøüþÿÇÿãÿñÿùÿÿ1.9.12~dfsg/windows/Setup/README0000644000000000000000000000342513214314510015016 0ustar rootrootThis folder contains a script to create an installer for windows. It uses 'CreateInstall Free'(http://www.createinstall.com), a little software allowing to make simple installers. You can use the 'jack.ci' script to make the installer. For that, you need to build the Code::Blocks workspace in order to have '.exe' and libraries. You also need 'qjackctl' binaries and libraries ('qjackctl.exe', 'mingwm10.dll', 'QtCore4.dll', 'QtGui.dll' and 'QtXml4.dll'). You can recompile qjackctl with qt4 or directly get the binaries. The five files are expected in the 'qjackctl' folder. You also need the Microsoft Visual C++ 2008 Redistributable Package (x86) (the vcrdist_x86.exe file) to be in src folder. If you need libjack.lib and libjackserver.lib to link with in MS Visual Studio, you can use the MS Tool lib.exe to create the .lib file from de .def. Just use : 'lib /DEF:libjackserver.def /OUT:libjackserver.lib' and 'lib /DEF:libjack.def /OUT:libjack.lib' to create the lib file. Or you can also use dlltool, from mingw suite : Just use : 'dlltool -l libjackserver.lib -D libjackserver.dll -d libjackserver.def' and 'dlltool -l libjack.lib -D libjack.dll -d libjack.def' Once all binaries are available, just execute the script in 'CreateInstall' to make 'setup.exe'. The setup will copy all binaries to a specified folder, register the JackRouter (in order to have it in the ASIO drivers list) and create some shortcuts in the start menu. It's a good and proper way to get jack installed on windows. 64 bits compilation ==================== - for some reasons CodeBlocks create libjack.dll.a and libjack.dll.def names. So the ".dll" part has to be removed before using "lib" tool to create ".lib" files. - to create 64 bits ".lib" files, the "/MACHINE:X64 option has to be used. 1.9.12~dfsg/windows/Setup/jack64.ci0000644000000000000000000002227413214314510015540 0ustar rootroot<*project version = 4 civer = "Free v4.14.5" winver = "2.8/6.1.7600" > . Jack_v1.9.12_64_setup.exe Jack Default - 2 1 nolimit disk%i.pak 1000 admin Verdana,8 English Green leftlogo .\src\logo_installer.bmp 0 1 .\src\README .\src\gpl_installer.rtf 0 1 1 1 defnorm 0 over 1 1 Uninstall - 2 1 0 1 1 My Demo <_>..\Release64\bin\libjack64.ainstlibovernewer0 <_>..\Release64\bin\libjack64.libinstlibovernewer0 <_>..\Release64\bin\libjack64.definstlibovernewer0 <_>..\Release64\bin\libjack64.dllwinovernewer0 <_>..\Release64\bin\libjackserver64.ainstlibovernewer0 <_>..\Release64\bin\libjackserver64.libinstlibovernewer0 <_>..\Release64\bin\libjackserver64.definstlibovernewer0 <_>..\Release64\bin\libjackserver64.dllwinovernewer0 <_>..\Release\bin\libjack.ainstlibovernewer0 <_>..\Release\bin\libjack.libinstlibovernewer0 <_>..\Release\bin\libjack.definstlibovernewer0 <_>..\Release\bin\libjack.dllsysovernewer0 <_>..\Release\bin\libjackserver.ainstlibovernewer0 <_>..\Release\bin\libjackserver.libinstlibovernewer0 <_>..\Release\bin\libjackserver.definstlibovernewer0 <_>..\Release\bin\libjackserver.dllsysovernewer0 <_>.\src\32bits\portaudio_x86.dllinstovernewer0 <_>..\Release64\bin\jack_connect.exeinstovernewer0 <_>..\Release64\bin\jack_disconnect.exeinstovernewer0 <_>..\Release64\bin\jack_load.exeinstovernewer0 <_>..\Release64\bin\jack_lsp.exeinstovernewer0 <_>..\Release64\bin\jack_metro.exeinstovernewer0 <_>..\Release64\bin\jack_unload.exeinstovernewer0 <_>..\Release64\bin\jack_midi_latency_test.exeinstovernewer0 <_>..\Release64\bin\jackd.exeinstovernewer0 <_>..\Release64\bin\jack\jack_net.dllwinjackovernewer0 <_>..\Release64\bin\jack\jack_netone.dllwinjackovernewer0 <_>..\Release64\bin\jack_netsource.exeinstovernewer0 <_>..\Release64\bin\jack\jack_dummy.dllwinjackovernewer0 <_>..\Release64\bin\jack\jack_loopback.dllwinjackovernewer0 <_>..\Release64\bin\jack\jack_winmme.dllwinjackovernewer0 <_>..\Release64\bin\jack\jack_portaudio.dllwinjackovernewer0 <_>..\Release64\bin\jack\netmanager.dllwinjackovernewer0 <_>..\Release64\bin\jack\audioadapter.dllwinjackovernewer0 <_>..\Release64\bin\jack\netadapter.dllwinjackovernewer0 <_>..\Release64\bin\jack_midi_dump.exeinstovernewer0 <_>..\..\common\jack\control.hinstincludes\jackovernewer0 <_>..\..\common\jack\intclient.hinstincludes\jackovernewer0 <_>..\..\common\jack\jack.hinstincludes\jackovernewer0 <_>..\..\common\jack\jslist.hinstincludes\jackovernewer0 <_>..\..\common\jack\midiport.hinstincludes\jackovernewer0 <_>..\..\common\jack\ringbuffer.hinstincludes\jackovernewer0 <_>..\..\common\jack\session.hinstincludes\jackovernewer0 <_>..\..\common\jack\statistics.hinstincludes\jackovernewer0 <_>..\..\common\jack\systemdeps.hinstincludes\jackovernewer1 <_>..\..\common\jack\thread.hinstincludes\jackovernewer0 <_>..\..\common\jack\transport.hinstincludes\jackovernewer0 <_>..\..\common\jack\types.hinstincludes\jackovernewer0 <_>..\..\common\jack\weakjack.hinstincludes\jackovernewer1 <_>..\..\common\jack\weakmacros.hinstincludes\jackovernewer1 <_>.\src\32bits\JackRouter.dllinst32bitsovernewer0 <_>.\src\32bits\JackRouter.iniinst32bitsovernewer0 <_>.\src\32bits\msvcr100.dllinst32bitsovernewer0 <_>.\src\32bits\msvcp100.dllinst32bitsovernewer0 <_>.\src\64bits\JackRouter.dllinst64bitsovernewer0 <_>.\src\64bits\JackRouter.iniinst64bitsovernewer0 <_>.\src\64bits\msvcr100.dllinst64bitsovernewer0 <_>.\src\64bits\msvcp100.dllinst64bitsovernewer0 <_>.\qjackctl\mingwm10.dllinstovernewer0 <_>.\qjackctl\qjackctl.exeinstovernewer0 <_>.\qjackctl\QtCore4.dllinstovernewer0 <_>.\qjackctl\QtGui4.dllinstovernewer0 <_>.\qjackctl\QtXml4.dllinstovernewer0 <_>.\qjackctl\libgcc_s_dw2-1.dllinstovernewer0 <_>.\src\COPYINGinstovernewer0 <_>.\src\READMEinstovernewer0 <_>progJack NetDriverinstjackd.exe-R -S -d netinst <_>progJack PortAudioinstjackd.exe-R -S -d portaudioinst <_>progJack Controlinstqjackctl.exeinstjackdmp.exe <_>progJack Commandsyscmd.exeinst <_>inst32bits\JackRouter.dll <_>inst64bits\JackRouter.dll Pathadd= 1.9.12~dfsg/windows/Setup/jack.ci0000644000000000000000000001754113214314510015367 0ustar rootroot<*project version = 4 civer = "Free v4.14.5" winver = "2.6/5.1.2600" > . Jack_v1.9.12_32_setup.exe Jack Default - 2 1 nolimit disk%i.pak 1000 admin Verdana,8 English Green leftlogo .\src\logo_installer.bmp 0 1 .\src\README .\src\gpl_installer.rtf 0 1 1 1 defnorm 0 over 1 1 Uninstall - 2 1 0 1 1 My Demo <_>..\Release\bin\libjack.ainstlibovernewer0 <_>..\Release\bin\libjack.libinstlibovernewer0 <_>..\Release\bin\libjack.definstlibovernewer0 <_>..\Release\bin\libjackserver.ainstlibovernewer0 <_>..\Release\bin\libjackserver.libinstlibovernewer0 <_>..\Release\bin\libjackserver.definstlibovernewer0 <_>..\Release\bin\jack_connect.exeinstovernewer0 <_>..\Release\bin\jack_disconnect.exeinstovernewer0 <_>..\Release\bin\jack_load.exeinstovernewer0 <_>..\Release\bin\jack_lsp.exeinstovernewer0 <_>..\Release\bin\jack_metro.exeinstovernewer0 <_>..\Release\bin\jack_unload.exeinstovernewer0 <_>..\Release\bin\jack_midi_latency_test.exeinstovernewer0 <_>..\Release\bin\jackd.exeinstovernewer0 <_>..\Release\bin\libjack.dllsysovernewer0 <_>..\Release\bin\libjackserver.dllsysovernewer0 <_>..\Release\bin\jack\jack_net.dllsysjackovernewer0 <_>..\Release\bin\jack\jack_netone.dllsysjackovernewer0 <_>..\Release\bin\jack_netsource.exeinstovernewer0 <_>..\Release\bin\jack\jack_dummy.dllsysjackovernewer0 <_>..\Release\bin\jack\jack_loopback.dllsysjackovernewer0 <_>..\Release\bin\jack\jack_winmme.dllsysjackovernewer0 <_>..\Release\bin\jack\jack_portaudio.dllsysjackovernewer0 <_>..\Release\bin\jack\netmanager.dllsysjackovernewer0 <_>..\Release\bin\jack\audioadapter.dllsysjackovernewer0 <_>..\Release\bin\jack\netadapter.dllsysjackovernewer0 <_>..\Release\bin\jack_midi_dump.exeinstovernewer0 <_>.\src\32bits\portaudio_x86.dllinstovernewer0 <_>..\..\common\jack\control.hinstincludes\jackovernewer0 <_>..\..\common\jack\intclient.hinstincludes\jackovernewer0 <_>..\..\common\jack\jack.hinstincludes\jackovernewer0 <_>..\..\common\jack\jslist.hinstincludes\jackovernewer0 <_>..\..\common\jack\midiport.hinstincludes\jackovernewer0 <_>..\..\common\jack\ringbuffer.hinstincludes\jackovernewer0 <_>..\..\common\jack\session.hinstincludes\jackovernewer0 <_>..\..\common\jack\statistics.hinstincludes\jackovernewer0 <_>..\..\common\jack\systemdeps.hinstincludes\jackovernewer1 <_>..\..\common\jack\thread.hinstincludes\jackovernewer0 <_>..\..\common\jack\transport.hinstincludes\jackovernewer0 <_>..\..\common\jack\types.hinstincludes\jackovernewer0 <_>..\..\common\jack\weakjack.hinstincludes\jackovernewer1 <_>..\..\common\jack\weakmacros.hinstincludes\jackovernewer1 <_>.\src\32bits\JackRouter.dllinst32bitsovernewer0 <_>.\src\32bits\JackRouter.iniinst32bitsovernewer0 <_>.\src\32bits\msvcr100.dllinst32bitsovernewer0 <_>.\src\32bits\msvcp100.dllinst32bitsovernewer0 <_>.\qjackctl\mingwm10.dllinstovernewer0 <_>.\qjackctl\qjackctl.exeinstovernewer0 <_>.\qjackctl\QtCore4.dllinstovernewer0 <_>.\qjackctl\QtGui4.dllinstovernewer0 <_>.\qjackctl\QtXml4.dllinstovernewer0 <_>.\qjackctl\libgcc_s_dw2-1.dllinstovernewer0 <_>.\src\COPYINGinstovernewer0 <_>.\src\READMEinstovernewer0 <_>progJack NetDriverinstjackd.exe-R -S -d netinst <_>progJack PortAudioinstjackd.exe-R -S -d portaudioinst <_>progJack Controlinstqjackctl.exeinstjackdmp.exe <_>progJack Commandsyscmd.exeinst <_>inst32bits\JackRouter.dll Pathadd= 1.9.12~dfsg/windows/jack_midi_dump.cbp0000644000000000000000000000707113214314510016464 0ustar rootroot 1.9.12~dfsg/windows/Release64/0000755000000000000000000000000013214314510014564 5ustar rootroot1.9.12~dfsg/windows/Release64/bin/0000755000000000000000000000000013244556535015356 5ustar rootroot1.9.12~dfsg/.travis.yml0000644000000000000000000000176513214314510013462 0ustar rootrootsudo: false os: - osx - linux language: - cpp compiler: - gcc - clang addons: apt: packages: - libsamplerate-dev - libsndfile-dev - libasound2-dev before_install: - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew outdated pkg-config || brew upgrade pkg-config; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install aften; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install libsamplerate; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install libsndfile; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install opus; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install readline; fi script: - if [ "$TRAVIS_OS_NAME" == "linux" ]; then ./waf configure --alsa; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then ./waf configure --opus=no --readline=no; fi - ./waf build matrix: exclude: - os: osx compiler: gcc 1.9.12~dfsg/solaris/0000755000000000000000000000000013214314510013014 5ustar rootroot1.9.12~dfsg/solaris/JackAtomic_os.h0000644000000000000000000000175713214314510015705 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAtomic_sun__ #define __JackAtomic_sun__ #include "JackTypes.h" #include static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) { return (atomic_cas_32((uint32_t*)addr, value, newvalue) == value); } #endif 1.9.12~dfsg/solaris/JackPlatformPlug_os.h0000644000000000000000000000501213214314510017071 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPlatformPlug_sun__ #define __JackPlatformPlug_sun__ #define jack_server_dir "/tmp" #define jack_client_dir "/tmp" #define JACK_DEFAULT_DRIVER "oss" namespace Jack { struct JackRequest; struct JackResult; class JackPosixMutex; class JackPosixThread; class JackFifo; class JackSocketServerChannel; class JackSocketClientChannel; class JackSocketServerNotifyChannel; class JackSocketNotifyChannel; class JackClientSocket; class JackNetUnixSocket; } /* __JackPlatformMutex__ */ #include "JackPosixMutex.h" namespace Jack {typedef JackPosixMutex JackMutex; } /* __JackPlatformThread__ */ #include "JackPosixThread.h" namespace Jack { typedef JackPosixThread JackThread; } /* __JackPlatformSynchro__ client activation */ #include "JackFifo.h" namespace Jack { typedef JackFifo JackSynchro; } /* __JackPlatformChannelTransaction__ */ #include "JackSocket.h" namespace Jack { typedef JackClientSocket JackChannelTransaction; } /* __JackPlatformProcessSync__ */ #include "JackPosixProcessSync.h" namespace Jack { typedef JackPosixProcessSync JackProcessSync; } /* __JackPlatformServerChannel__ */ #include "JackSocketServerChannel.h" namespace Jack { typedef JackSocketServerChannel JackServerChannel; } /* __JackPlatformClientChannel__ */ #include "JackSocketClientChannel.h" namespace Jack { typedef JackSocketClientChannel JackClientChannel; } /* __JackPlatformServerNotifyChannel__ */ #include "JackSocketServerNotifyChannel.h" namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; } /* __JackPlatformNotifyChannel__ */ #include "JackSocketNotifyChannel.h" namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; } /* __JackPlatformNetSocket__ */ #include "JackNetUnixSocket.h" namespace Jack { typedef JackNetUnixSocket JackNetSocket; } #endif 1.9.12~dfsg/solaris/oss/0000755000000000000000000000000013214314510013620 5ustar rootroot1.9.12~dfsg/solaris/oss/JackOSSAdapter.cpp0000644000000000000000000005606213214314510017073 0ustar rootroot/* Copyright (C) 2008 Grame & RTL 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackOSSAdapter.h" #include "JackServerGlobals.h" #include "JackEngineControl.h" #include "memops.h" #include #include #include #include #include namespace Jack { inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; } static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int chcount, int bits) { switch (bits) { case 16: { signed short *s16src = (signed short*)src; s16src += channel; sample_move_dS_s16(dst, (char*)s16src, nframes, chcount<<1); break; } case 24: { signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); break; } case 32: { signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); break; } } } static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int chcount, int bits) { switch (bits) { case 16: { signed short *s16dst = (signed short*)dst; s16dst += channel; sample_move_d16_sS((char*)s16dst, src, nframes, chcount<<1, NULL); // No dithering for now... break; } case 24: { signed int *s32dst = (signed int*)dst; s32dst += channel; sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... break; } case 32: { signed int *s32dst = (signed int*)dst; s32dst += channel; sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); break; } } } void JackOSSAdapter::SetSampleFormat() { switch (fBits) { case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */ fSampleFormat = AFMT_S24_NE; fSampleSize = sizeof(int); break; case 32: /* native-endian 32-bit integer */ fSampleFormat = AFMT_S32_NE; fSampleSize = sizeof(int); break; case 16: /* native-endian 16-bit integer */ default: fSampleFormat = AFMT_S16_NE; fSampleSize = sizeof(short); break; } } JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) :JackAudioAdapterInterface(buffer_size, sample_rate) ,fThread(this), fInFD(-1), fOutFD(-1), fBits(OSS_DRIVER_DEF_BITS), fSampleFormat(0), fNperiods(OSS_DRIVER_DEF_NPERIODS), fRWMode(0), fIgnoreHW(true), fExcl(false), fInputBufferSize(0), fOutputBufferSize(0), fInputBuffer(NULL), fOutputBuffer(NULL), fFirstCycle(true) { const JSList* node; const jack_driver_param_t* param; fCaptureChannels = 2; fPlaybackChannels = 2; strcpy(fCaptureDriverName, OSS_DRIVER_DEF_DEV); strcpy(fPlaybackDriverName, OSS_DRIVER_DEF_DEV); for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'r': SetAdaptedSampleRate(param->value.ui); break; case 'p': SetAdaptedBufferSize(param->value.ui); break; case 'n': fNperiods = param->value.ui; break; case 'w': fBits = param->value.i; break; case 'i': fCaptureChannels = param->value.ui; break; case 'o': fPlaybackChannels = param->value.ui; break; case 'e': fExcl = true; break; case 'C': fRWMode |= kRead; if (strcmp(param->value.str, "none") != 0) { strcpy(fCaptureDriverName, param->value.str); } break; case 'P': fRWMode |= kWrite; if (strcmp(param->value.str, "none") != 0) { strcpy(fPlaybackDriverName, param->value.str); } break; case 'd': fRWMode |= kRead; fRWMode |= kWrite; strcpy(fCaptureDriverName, param->value.str); strcpy(fPlaybackDriverName, param->value.str); break; case 'b': fIgnoreHW = true; break; case 'q': fQuality = param->value.ui; break; case 'g': fRingbufferCurSize = param->value.ui; fAdaptative = false; break; } } fRWMode |= kRead; fRWMode |= kWrite; } void JackOSSAdapter::DisplayDeviceInfo() { audio_buf_info info; oss_audioinfo ai_in, ai_out; memset(&info, 0, sizeof(audio_buf_info)); int cap = 0; // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html jack_info("Audio Interface Description :"); jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fAdaptedSampleRate, fSampleFormat, fRWMode); if (fRWMode & kWrite) { oss_sysinfo si; if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { jack_error("JackOSSAdapter::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("OSS product %s", si.product); jack_info("OSS version %s", si.version); jack_info("OSS version num %d", si.versionnum); jack_info("OSS numaudios %d", si.numaudios); jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } jack_info("Output capabilities - %d channels : ", fPlaybackChannels); jack_info("Output block size = %d", fOutputBufferSize); if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); } if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } if (fRWMode & kRead) { oss_sysinfo si; if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { jack_error("JackOSSAdapter::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("OSS product %s", si.product); jack_info("OSS version %s", si.version); jack_info("OSS version num %d", si.versionnum); jack_info("OSS numaudios %d", si.numaudios); jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } jack_info("Input capabilities - %d channels : ", fCaptureChannels); jack_info("Input block size = %d", fInputBufferSize); if (ioctl(fInFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); } if (ioctl(fInFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } if (ioctl(fInFD, SNDCTL_AUDIOINFO, &ai_in) != -1) { jack_info("Using audio engine %d = %s for input", ai_in.dev, ai_in.name); } if (ioctl(fOutFD, SNDCTL_AUDIOINFO, &ai_out) != -1) { jack_info("Using audio engine %d = %s for output", ai_out.dev, ai_out.name); } if (ai_in.rate_source != ai_out.rate_source) { jack_info("Warning : input and output are not necessarily driven by the same clock!"); } } int JackOSSAdapter::OpenInput() { int flags = 0; int gFragFormat; int cur_sample_format, cur_capture_channels; jack_nframes_t cur_sample_rate; if (fCaptureChannels == 0) fCaptureChannels = 2; if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackOSSAdapter::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } if (fExcl) { if (ioctl(fInFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackOSSAdapter::OpenInput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } } gFragFormat = (2 << 16) + int2pow2(fAdaptedBufferSize * fSampleSize * fCaptureChannels); if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackOSSAdapter::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } cur_sample_format = fSampleFormat; if (ioctl(fInFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { jack_error("JackOSSAdapter::OpenInput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_format != fSampleFormat) { jack_info("JackOSSAdapter::OpenInput driver forced the sample format %ld", fSampleFormat); } cur_capture_channels = fCaptureChannels; if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { jack_error("JackOSSAdapter::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_capture_channels != fCaptureChannels) { jack_info("JackOSSAdapter::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); } cur_sample_rate = fAdaptedSampleRate; if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fAdaptedSampleRate) == -1) { jack_error("JackOSSAdapter::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_rate != fAdaptedSampleRate) { jack_info("JackOSSAdapter::OpenInput driver forced the sample rate %ld", fAdaptedSampleRate); } fInputBufferSize = 0; if (ioctl(fInFD, SNDCTL_DSP_GETBLKSIZE, &fInputBufferSize) == -1) { jack_error("JackOSSAdapter::OpenInput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (fInputBufferSize != fAdaptedBufferSize * fSampleSize * fCaptureChannels) { if (fIgnoreHW) { jack_info("JackOSSAdapter::OpenInput driver forced buffer size %ld", fOutputBufferSize); } else { jack_error("JackOSSAdapter::OpenInput wanted buffer size cannot be obtained"); goto error; } } fInputBuffer = (void*)calloc(fInputBufferSize, 1); assert(fInputBuffer); fInputSampleBuffer = (float**)malloc(fCaptureChannels * sizeof(float*)); assert(fInputSampleBuffer); for (int i = 0; i < fCaptureChannels; i++) { fInputSampleBuffer[i] = (float*)malloc(fAdaptedBufferSize * sizeof(float)); assert(fInputSampleBuffer[i]); } return 0; error: ::close(fInFD); return -1; } int JackOSSAdapter::OpenOutput() { int flags = 0; int gFragFormat; int cur_sample_format, cur_playback_channels; jack_nframes_t cur_sample_rate; if (fPlaybackChannels == 0) fPlaybackChannels = 2; if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackOSSAdapter::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } if (fExcl) { if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackOSSAdapter::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } } gFragFormat = (2 << 16) + int2pow2(fAdaptedBufferSize * fSampleSize * fPlaybackChannels); if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackOSSAdapter::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } cur_sample_format = fSampleFormat; if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { jack_error("JackOSSAdapter::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_format != fSampleFormat) { jack_info("JackOSSAdapter::OpenOutput driver forced the sample format %ld", fSampleFormat); } cur_playback_channels = fPlaybackChannels; if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { jack_error("JackOSSAdapter::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_playback_channels != fPlaybackChannels) { jack_info("JackOSSAdapter::OpenOutput driver forced the number of playback channels %ld", fPlaybackChannels); } cur_sample_rate = fAdaptedSampleRate; if (ioctl(fOutFD, SNDCTL_DSP_SPEED, &fAdaptedSampleRate) == -1) { jack_error("JackOSSAdapter::OpenOutput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_rate != fAdaptedSampleRate) { jack_info("JackOSSAdapter::OpenInput driver forced the sample rate %ld", fAdaptedSampleRate); } fOutputBufferSize = 0; if (ioctl(fOutFD, SNDCTL_DSP_GETBLKSIZE, &fOutputBufferSize) == -1) { jack_error("JackOSSAdapter::OpenOutput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (fOutputBufferSize != fAdaptedBufferSize * fSampleSize * fPlaybackChannels) { if (fIgnoreHW) { jack_info("JackOSSAdapter::OpenOutput driver forced buffer size %ld", fOutputBufferSize); } else { jack_error("JackOSSAdapter::OpenInput wanted buffer size cannot be obtained"); goto error; } } fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); assert(fOutputBuffer); fOutputSampleBuffer = (float**)malloc(fPlaybackChannels * sizeof(float*)); assert(fOutputSampleBuffer); for (int i = 0; i < fPlaybackChannels; i++) { fOutputSampleBuffer[i] = (float*)malloc(fAdaptedBufferSize * sizeof(float)); assert(fOutputSampleBuffer[i]); } fFirstCycle = true; return 0; error: ::close(fOutFD); return -1; } int JackOSSAdapter::Open() { SetSampleFormat(); if ((fRWMode & kRead) && (OpenInput() < 0)) { return -1; } if ((fRWMode & kWrite) && (OpenOutput() < 0)) { return -1; } // In duplex mode, check that input and output use the same buffer size if ((fRWMode & kRead) && (fRWMode & kWrite) && (fInputBufferSize != fOutputBufferSize)) { jack_error("JackOSSAdapter::OpenAux input and output buffer size are not the same!!"); goto error; } DisplayDeviceInfo(); //start adapter thread if (fThread.StartSync() < 0) { jack_error ( "Cannot start audioadapter thread" ); return -1; } //turn the thread realtime fThread.AcquireRealTime(JackServerGlobals::fInstance->GetEngineControl()->fClientPriority); return 0; error: CloseAux(); return -1; } int JackOSSAdapter::Close() { #ifdef JACK_MONITOR fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif fThread.Stop(); CloseAux(); return 0; } void JackOSSAdapter::CloseAux() { if (fRWMode & kRead) { close(fInFD); fInFD = -1; } if (fRWMode & kWrite) { close(fOutFD); fOutFD = -1; } free(fInputBuffer); fInputBuffer = NULL; free(fOutputBuffer); fOutputBuffer = NULL; for (int i = 0; i < fCaptureChannels; i++) { free(fInputSampleBuffer[i]); } free(fInputSampleBuffer); for (int i = 0; i < fPlaybackChannels; i++) { free(fOutputSampleBuffer[i]); } free(fOutputSampleBuffer); } int JackOSSAdapter::Read() { ssize_t count = ::read(fInFD, fInputBuffer, fInputBufferSize); if (count < fInputBufferSize) { jack_error("JackOSSAdapter::Read error bytes read = %ld", count); return -1; } else { for (int i = 0; i < fCaptureChannels; i++) { CopyAndConvertIn(fInputSampleBuffer[i], fInputBuffer, fAdaptedBufferSize, i, fCaptureChannels, fBits); } return 0; } } int JackOSSAdapter::Write() { ssize_t count; // Maybe necessay to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html if (fFirstCycle) { fFirstCycle = false; memset(fOutputBuffer, 0, fOutputBufferSize); // Prefill ouput buffer for (int i = 0; i < fNperiods; i++) { count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); if (count < fOutputBufferSize) { jack_error("JackOSSDriver::Write error bytes written = %ld", count); return -1; } } int delay; if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } delay /= fSampleSize * fPlaybackChannels; jack_info("JackOSSDriver::Write output latency frames = %ld", delay); } for (int i = 0; i < fPlaybackChannels; i++) { CopyAndConvertOut(fOutputBuffer, fOutputSampleBuffer[i], fAdaptedBufferSize, i, fCaptureChannels, fBits); } count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); if (count < fOutputBufferSize) { jack_error("JackOSSAdapter::Write error bytes written = %ld", count); return -1; } else { return 0; } } bool JackOSSAdapter::Execute() { //read data from audio interface if (Read() < 0) return false; PushAndPull(fInputSampleBuffer, fOutputSampleBuffer, fAdaptedBufferSize); //write data to audio interface if (Write() < 0) return false; return true; } int JackOSSAdapter::SetBufferSize(jack_nframes_t buffer_size) { JackAudioAdapterInterface::SetBufferSize(buffer_size); Close(); return Open(); } } // namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler); value.ui = OSS_DRIVER_DEF_FS; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = OSS_DRIVER_DEF_BLKSIZE; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = OSS_DRIVER_DEF_NPERIODS; jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods to prefill output buffer", NULL); value.i = OSS_DRIVER_DEF_BITS; jack_driver_descriptor_add_parameter(desc, &filler, "wordlength", 'w', JackDriverParamInt, &value, NULL, "Word length", NULL); value.ui = OSS_DRIVER_DEF_INS; jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamUInt, &value, NULL, "Capture channels", NULL); value.ui = OSS_DRIVER_DEF_OUTS; jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamUInt, &value, NULL, "Playback channels", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "excl", 'e', JackDriverParamBool, &value, NULL, "Exclusif (O_EXCL) access mode", NULL); strcpy(value.str, OSS_DRIVER_DEF_DEV); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input device", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Output device", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "OSS device name", NULL); value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "ignorehwbuf", 'b', JackDriverParamBool, &value, NULL, "Ignore hardware period size", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL); value.i = 32768; jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)"); return desc; } #ifdef __cplusplus } #endif 1.9.12~dfsg/solaris/oss/JackOSSDriver.cpp0000644000000000000000000007442413214314510016750 0ustar rootroot/* Copyright (C) 2003-2007 Jussi Laako Copyright (C) 2008 Grame & RTL 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "driver_interface.h" #include "JackThreadedDriver.h" #include "JackDriverLoader.h" #include "JackOSSDriver.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackError.h" #include "JackTime.h" #include "JackShmMem.h" #include "memops.h" #include #include #include #include #include #include using namespace std; namespace Jack { #ifdef JACK_MONITOR #define CYCLE_POINTS 500000 struct OSSCycle { jack_time_t fBeforeRead; jack_time_t fAfterRead; jack_time_t fAfterReadConvert; jack_time_t fBeforeWrite; jack_time_t fAfterWrite; jack_time_t fBeforeWriteConvert; }; struct OSSCycleTable { jack_time_t fBeforeFirstWrite; jack_time_t fAfterFirstWrite; OSSCycle fTable[CYCLE_POINTS]; }; OSSCycleTable gCycleTable; int gCycleCount = 0; #endif inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; } static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int chcount, int bits) { switch (bits) { case 16: { signed short *s16src = (signed short*)src; s16src += channel; sample_move_dS_s16(dst, (char*)s16src, nframes, chcount<<1); break; } case 24: { signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); break; } case 32: { signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); break; } } } static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int chcount, int bits) { switch (bits) { case 16: { signed short *s16dst = (signed short*)dst; s16dst += channel; sample_move_d16_sS((char*)s16dst, src, nframes, chcount<<1, NULL); // No dithering for now... break; } case 24: { signed int *s32dst = (signed int*)dst; s32dst += channel; sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... break; } case 32: { signed int *s32dst = (signed int*)dst; s32dst += channel; sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); break; } } } void JackOSSDriver::SetSampleFormat() { switch (fBits) { case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */ fSampleFormat = AFMT_S24_NE; fSampleSize = sizeof(int); break; case 32: /* native-endian 32-bit integer */ fSampleFormat = AFMT_S32_NE; fSampleSize = sizeof(int); break; case 16: /* native-endian 16-bit integer */ default: fSampleFormat = AFMT_S16_NE; fSampleSize = sizeof(short); break; } } void JackOSSDriver::DisplayDeviceInfo() { audio_buf_info info; oss_audioinfo ai_in, ai_out; memset(&info, 0, sizeof(audio_buf_info)); int cap = 0; // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html jack_info("Audio Interface Description :"); jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); if (fRWMode & kWrite) { oss_sysinfo si; if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("OSS product %s", si.product); jack_info("OSS version %s", si.version); jack_info("OSS version num %d", si.versionnum); jack_info("OSS numaudios %d", si.numaudios); jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } jack_info("Output capabilities - %d channels : ", fPlaybackChannels); jack_info("Output block size = %d", fOutputBufferSize); if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); } if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } if (fRWMode & kRead) { oss_sysinfo si; if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("OSS product %s", si.product); jack_info("OSS version %s", si.version); jack_info("OSS version num %d", si.versionnum); jack_info("OSS numaudios %d", si.numaudios); jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } jack_info("Input capabilities - %d channels : ", fCaptureChannels); jack_info("Input block size = %d", fInputBufferSize); if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); } if (ioctl(fInFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } if (ai_in.rate_source != ai_out.rate_source) { jack_info("Warning : input and output are not necessarily driven by the same clock!"); } } int JackOSSDriver::OpenInput() { int flags = 0; int gFragFormat; int cur_capture_channels; int cur_sample_format; jack_nframes_t cur_sample_rate; if (fCaptureChannels == 0) fCaptureChannels = 2; if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackOSSDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } jack_log("JackOSSDriver::OpenInput input fInFD = %d", fInFD); if (fExcl) { if (ioctl(fInFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackOSSDriver::OpenInput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } } gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackOSSDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } cur_sample_format = fSampleFormat; if (ioctl(fInFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { jack_error("JackOSSDriver::OpenInput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_format != fSampleFormat) { jack_info("JackOSSDriver::OpenInput driver forced the sample format %ld", fSampleFormat); } cur_capture_channels = fCaptureChannels; if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { jack_error("JackOSSDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_capture_channels != fCaptureChannels) { jack_info("JackOSSDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); } cur_sample_rate = fEngineControl->fSampleRate; if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { jack_error("JackOSSDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_rate != fEngineControl->fSampleRate) { jack_info("JackOSSDriver::OpenInput driver forced the sample rate %ld", fEngineControl->fSampleRate); } fInputBufferSize = 0; if (ioctl(fInFD, SNDCTL_DSP_GETBLKSIZE, &fInputBufferSize) == -1) { jack_error("JackOSSDriver::OpenInput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (fInputBufferSize != fEngineControl->fBufferSize * fSampleSize * fCaptureChannels) { if (fIgnoreHW) { int new_buffer_size = fInputBufferSize / (fSampleSize * fCaptureChannels); jack_info("JackOSSDriver::OpenInput driver forced buffer size %ld", new_buffer_size); JackAudioDriver::SetBufferSize(new_buffer_size); // never fails } else { jack_error("JackOSSDriver::OpenInput wanted buffer size cannot be obtained"); goto error; } } fInputBuffer = (void*)calloc(fInputBufferSize, 1); assert(fInputBuffer); return 0; error: ::close(fInFD); return -1; } int JackOSSDriver::OpenOutput() { int flags = 0; int gFragFormat; int cur_sample_format; int cur_playback_channels; jack_nframes_t cur_sample_rate; if (fPlaybackChannels == 0) fPlaybackChannels = 2; if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackOSSDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } jack_log("JackOSSDriver::OpenOutput output fOutFD = %d", fOutFD); if (fExcl) { if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } } gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } cur_sample_format = fSampleFormat; if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_format != fSampleFormat) { jack_info("JackOSSDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); } cur_playback_channels = fPlaybackChannels; if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_playback_channels != fPlaybackChannels) { jack_info("JackOSSDriver::OpenOutput driver forced the number of playback channels %ld", fPlaybackChannels); } cur_sample_rate = fEngineControl->fSampleRate; if (ioctl(fOutFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_rate != fEngineControl->fSampleRate) { jack_info("JackOSSDriver::OpenInput driver forced the sample rate %ld", fEngineControl->fSampleRate); } fOutputBufferSize = 0; if (ioctl(fOutFD, SNDCTL_DSP_GETBLKSIZE, &fOutputBufferSize) == -1) { jack_error("JackOSSDriver::OpenOutput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (fOutputBufferSize != fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels) { if (fIgnoreHW) { int new_buffer_size = fOutputBufferSize / (fSampleSize * fPlaybackChannels); jack_info("JackOSSDriver::OpenOutput driver forced buffer size %ld", new_buffer_size); JackAudioDriver::SetBufferSize(new_buffer_size); // never fails } else { jack_error("JackOSSDriver::OpenInput wanted buffer size cannot be obtained"); goto error; } } fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); fFirstCycle = true; assert(fOutputBuffer); return 0; error: ::close(fOutFD); return -1; } int JackOSSDriver::Open(jack_nframes_t nframes, int user_nperiods, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool excl, bool monitor, const char* capture_driver_uid, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency, int bits, bool ignorehwbuf) { // Generic JackAudioDriver Open if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { return -1; } else { if (!fEngineControl->fSyncMode) { jack_error("Cannot run in asynchronous mode, use the -S parameter for jackd"); return -1; } fRWMode |= ((capturing) ? kRead : 0); fRWMode |= ((playing) ? kWrite : 0); fBits = bits; fIgnoreHW = ignorehwbuf; fNperiods = user_nperiods; fExcl = excl; #ifdef JACK_MONITOR // Force memory page in memset(&gCycleTable, 0, sizeof(gCycleTable)); #endif if (OpenAux() < 0) { Close(); return -1; } else { return 0; } } } int JackOSSDriver::Close() { #ifdef JACK_MONITOR FILE* file = fopen("OSSProfiling.log", "w"); if (file) { jack_info("Writing OSS driver timing data...."); for (int i = 1; i < gCycleCount; i++) { int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); } fclose(file); } else { jack_error("JackOSSDriver::Close : cannot open OSSProfiling.log file"); } file = fopen("TimingOSS.plot", "w"); if (file == NULL) { jack_error("JackOSSDriver::Close cannot open TimingOSS.plot file"); } else { fprintf(file, "set grid\n"); fprintf(file, "set title \"OSS audio driver timing\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot \"OSSProfiling.log\" using 1 title \"Driver read wait\" with lines, \ \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); fprintf(file, "set output 'TimingOSS.pdf\n"); fprintf(file, "set terminal pdf\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"OSS audio driver timing\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot \"OSSProfiling.log\" using 1 title \"Driver read wait\" with lines, \ \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); fclose(file); } #endif int res = JackAudioDriver::Close(); CloseAux(); return res; } int JackOSSDriver::OpenAux() { SetSampleFormat(); if ((fRWMode & kRead) && (OpenInput() < 0)) { return -1; } if ((fRWMode & kWrite) && (OpenOutput() < 0)) { return -1; } // In duplex mode, check that input and output use the same buffer size /* 10/02/09 : desactivated for now, needs more check (only needed when *same* device is used for input and output ??) if ((fRWMode & kRead) && (fRWMode & kWrite) && (fInputBufferSize != fOutputBufferSize)) { jack_error("JackOSSDriver::OpenAux input and output buffer size are not the same!!"); return -1; } */ DisplayDeviceInfo(); return 0; } void JackOSSDriver::CloseAux() { if (fRWMode & kRead && fInFD > 0) { close(fInFD); fInFD = -1; } if (fRWMode & kWrite && fOutFD > 0) { close(fOutFD); fOutFD = -1; } if (fInputBuffer) free(fInputBuffer); fInputBuffer = NULL; if (fOutputBuffer) free(fOutputBuffer); fOutputBuffer = NULL; } int JackOSSDriver::Read() { if (fInFD < 0) { // Keep begin cycle time JackDriver::CycleTakeBeginTime(); return 0; } ssize_t count; #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fBeforeRead = GetMicroSeconds(); #endif audio_errinfo ei_in; count = ::read(fInFD, fInputBuffer, fInputBufferSize); #ifdef JACK_MONITOR if (count > 0 && count != (int)fInputBufferSize) jack_log("JackOSSDriver::Read count = %ld", count / (fSampleSize * fCaptureChannels)); gCycleTable.fTable[gCycleCount].fAfterRead = GetMicroSeconds(); #endif // XRun detection if (ioctl(fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { if (ei_in.rec_overruns > 0 ) { jack_error("JackOSSDriver::Read overruns"); jack_time_t cur_time = GetMicroSeconds(); NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... } if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); } } if (count < 0) { jack_log("JackOSSDriver::Read error = %s", strerror(errno)); return -1; } else if (count < (int)fInputBufferSize) { jack_error("JackOSSDriver::Read error bytes read = %ld", count); return -1; } else { // Keep begin cycle time JackDriver::CycleTakeBeginTime(); for (int i = 0; i < fCaptureChannels; i++) { if (fGraphManager->GetConnectionsNum(fCapturePortList[i]) > 0) { CopyAndConvertIn(GetInputBuffer(i), fInputBuffer, fEngineControl->fBufferSize, i, fCaptureChannels, fBits); } } #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fAfterReadConvert = GetMicroSeconds(); #endif return 0; } } int JackOSSDriver::Write() { if (fOutFD < 0) { // Keep end cycle time JackDriver::CycleTakeEndTime(); return 0; } ssize_t count; audio_errinfo ei_out; // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html if (fFirstCycle) { fFirstCycle = false; memset(fOutputBuffer, 0, fOutputBufferSize); // Prefill ouput buffer for (int i = 0; i < fNperiods; i++) { count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); if (count < (int)fOutputBufferSize) { jack_error("JackOSSDriver::Write error bytes written = %ld", count); return -1; } } int delay; if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } delay /= fSampleSize * fPlaybackChannels; jack_info("JackOSSDriver::Write output latency frames = %ld", delay); } #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fBeforeWriteConvert = GetMicroSeconds(); #endif memset(fOutputBuffer, 0, fOutputBufferSize); for (int i = 0; i < fPlaybackChannels; i++) { if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { CopyAndConvertOut(fOutputBuffer, GetOutputBuffer(i), fEngineControl->fBufferSize, i, fPlaybackChannels, fBits); } } #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fBeforeWrite = GetMicroSeconds(); #endif // Keep end cycle time JackDriver::CycleTakeEndTime(); count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); #ifdef JACK_MONITOR if (count > 0 && count != (int)fOutputBufferSize) jack_log("JackOSSDriver::Write count = %ld", count / (fSampleSize * fPlaybackChannels)); gCycleTable.fTable[gCycleCount].fAfterWrite = GetMicroSeconds(); gCycleCount = (gCycleCount == CYCLE_POINTS - 1) ? gCycleCount: gCycleCount + 1; #endif // XRun detection if (ioctl(fOutFD, SNDCTL_DSP_GETERROR, &ei_out) == 0) { if (ei_out.play_underruns > 0) { jack_error("JackOSSDriver::Write underruns"); jack_time_t cur_time = GetMicroSeconds(); NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... } if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); } } if (count < 0) { jack_log("JackOSSDriver::Write error = %s", strerror(errno)); return -1; } else if (count < (int)fOutputBufferSize) { jack_error("JackOSSDriver::Write error bytes written = %ld", count); return -1; } else { return 0; } } int JackOSSDriver::SetBufferSize(jack_nframes_t buffer_size) { CloseAux(); JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails return OpenAux(); } int JackOSSDriver::ProcessSync() { // Read input buffers for the current cycle if (Read() < 0) { jack_error("ProcessSync: read error, skip cycle"); return 0; // Non fatal error here, skip cycle, but continue processing... } if (fIsMaster) { ProcessGraphSync(); } else { ResumeRefNum(); } // Write output buffers for the current cycle if (Write() < 0) { jack_error("JackAudioDriver::ProcessSync: write error, skip cycle"); return 0; // Non fatal error here, skip cycle, but continue processing... } return 0; } } // end of namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("oss", JackDriverMaster, "OSS API based audio backend", &filler); value.ui = OSS_DRIVER_DEF_FS; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = OSS_DRIVER_DEF_BLKSIZE; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = OSS_DRIVER_DEF_NPERIODS; jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods to prefill output buffer", NULL); value.i = OSS_DRIVER_DEF_BITS; jack_driver_descriptor_add_parameter(desc, &filler, "wordlength", 'w', JackDriverParamInt, &value, NULL, "Word length", NULL); value.ui = OSS_DRIVER_DEF_INS; jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Capture channels", NULL); value.ui = OSS_DRIVER_DEF_OUTS; jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Playback channels", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "excl", 'e', JackDriverParamBool, &value, NULL, "Exclusif (O_EXCL) access mode", NULL); strcpy(value.str, OSS_DRIVER_DEF_DEV); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input device", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Output device", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "OSS device name", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "ignorehwbuf", 'b', JackDriverParamBool, &value, NULL, "Ignore hardware period size", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { int bits = OSS_DRIVER_DEF_BITS; jack_nframes_t srate = OSS_DRIVER_DEF_FS; jack_nframes_t frames_per_interrupt = OSS_DRIVER_DEF_BLKSIZE; const char* capture_pcm_name = OSS_DRIVER_DEF_DEV; const char* playback_pcm_name = OSS_DRIVER_DEF_DEV; bool capture = false; bool playback = false; int chan_in = 0; int chan_out = 0; bool monitor = false; bool excl = false; unsigned int nperiods = OSS_DRIVER_DEF_NPERIODS; const JSList *node; const jack_driver_param_t *param; bool ignorehwbuf = false; jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t *)node->data; switch (param->character) { case 'r': srate = param->value.ui; break; case 'p': frames_per_interrupt = (unsigned int)param->value.ui; break; case 'n': nperiods = (unsigned int)param->value.ui; break; case 'w': bits = param->value.i; break; case 'i': chan_in = (int)param->value.ui; break; case 'o': chan_out = (int)param->value.ui; break; case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { capture_pcm_name = param->value.str; } break; case 'P': playback = true; if (strcmp(param->value.str, "none") != 0) { playback_pcm_name = param->value.str; } break; case 'd': playback_pcm_name = param->value.str; capture_pcm_name = param->value.str; break; case 'b': ignorehwbuf = true; break; case 'e': excl = true; break; case 'I': systemic_input_latency = param->value.ui; break; case 'O': systemic_output_latency = param->value.ui; break; } } // duplex is the default if (!capture && !playback) { capture = true; playback = true; } Jack::JackOSSDriver* oss_driver = new Jack::JackOSSDriver("system", "oss", engine, table); Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(oss_driver); // Special open for OSS driver... if (oss_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, ignorehwbuf) == 0) { return threaded_driver; } else { delete threaded_driver; // Delete the decorated driver return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/solaris/oss/JackBoomerDriver.cpp0000644000000000000000000010255213214314510017521 0ustar rootroot/* Copyright (C) 2009 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "driver_interface.h" #include "JackThreadedDriver.h" #include "JackDriverLoader.h" #include "JackBoomerDriver.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackError.h" #include "JackTime.h" #include "JackShmMem.h" #include "JackGlobals.h" #include "memops.h" #include #include #include #include #include #include using namespace std; namespace Jack { #ifdef JACK_MONITOR #define CYCLE_POINTS 500000 struct OSSCycle { jack_time_t fBeforeRead; jack_time_t fAfterRead; jack_time_t fAfterReadConvert; jack_time_t fBeforeWrite; jack_time_t fAfterWrite; jack_time_t fBeforeWriteConvert; }; struct OSSCycleTable { jack_time_t fBeforeFirstWrite; jack_time_t fAfterFirstWrite; OSSCycle fTable[CYCLE_POINTS]; }; OSSCycleTable gCycleTable; int gCycleReadCount = 0; int gCycleWriteCount = 0; #endif inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; } static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int byte_skip, int bits) { switch (bits) { case 16: { signed short *s16src = (signed short*)src; s16src += channel; sample_move_dS_s16(dst, (char*)s16src, nframes, byte_skip); break; } case 24: { signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s24(dst, (char*)s32src, nframes, byte_skip); break; } case 32: { signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s32u24(dst, (char*)s32src, nframes, byte_skip); break; } } } static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int byte_skip, int bits) { switch (bits) { case 16: { signed short *s16dst = (signed short*)dst; s16dst += channel; sample_move_d16_sS((char*)s16dst, src, nframes, byte_skip, NULL); // No dithering for now... break; } case 24: { signed int *s32dst = (signed int*)dst; s32dst += channel; sample_move_d24_sS((char*)s32dst, src, nframes, byte_skip, NULL); break; } case 32: { signed int *s32dst = (signed int*)dst; s32dst += channel; sample_move_d32u24_sS((char*)s32dst, src, nframes, byte_skip, NULL); break; } } } void JackBoomerDriver::SetSampleFormat() { switch (fBits) { case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */ fSampleFormat = AFMT_S24_NE; fSampleSize = 4; break; case 32: /* native-endian 32-bit integer */ fSampleFormat = AFMT_S32_NE; fSampleSize = 4; break; case 16: /* native-endian 16-bit integer */ default: fSampleFormat = AFMT_S16_NE; fSampleSize = 2; break; } } void JackBoomerDriver::DisplayDeviceInfo() { audio_buf_info info; oss_audioinfo ai_in, ai_out; memset(&info, 0, sizeof(audio_buf_info)); int cap = 0; // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html jack_info("Audio Interface Description :"); jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); if (fRWMode & kWrite) { oss_sysinfo si; if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("OSS product %s", si.product); jack_info("OSS version %s", si.version); jack_info("OSS version num %d", si.versionnum); jack_info("OSS numaudios %d", si.numaudios); jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } jack_info("Output capabilities - %d channels : ", fPlaybackChannels); jack_info("Output block size = %d", fOutputBufferSize); if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); fFragmentSize = info.fragsize; } if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } if (fRWMode & kRead) { oss_sysinfo si; if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("OSS product %s", si.product); jack_info("OSS version %s", si.version); jack_info("OSS version num %d", si.versionnum); jack_info("OSS numaudios %d", si.numaudios); jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } jack_info("Input capabilities - %d channels : ", fCaptureChannels); jack_info("Input block size = %d", fInputBufferSize); if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); } if (ioctl(fInFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } if (ai_in.rate_source != ai_out.rate_source) { jack_info("Warning : input and output are not necessarily driven by the same clock!"); } } JackBoomerDriver::JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), fInFD(-1), fOutFD(-1), fBits(0), fSampleFormat(0), fNperiods(0), fSampleSize(0), fFragmentSize(0), fRWMode(0), fExcl(false), fSyncIO(false), fInputBufferSize(0), fOutputBufferSize(0), fInputBuffer(NULL), fOutputBuffer(NULL), fInputThread(&fInputHandler), fOutputThread(&fOutputHandler), fInputHandler(this), fOutputHandler(this) { sem_init(&fReadSema, 0, 0); sem_init(&fWriteSema, 0, 0); } JackBoomerDriver::~JackBoomerDriver() { sem_destroy(&fReadSema); sem_destroy(&fWriteSema); } int JackBoomerDriver::OpenInput() { int flags = 0; int gFragFormat; int cur_capture_channels; int cur_sample_format; jack_nframes_t cur_sample_rate; if (fCaptureChannels == 0) fCaptureChannels = 2; if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackBoomerDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } jack_log("JackBoomerDriver::OpenInput input fInFD = %d", fInFD); if (fExcl) { if (ioctl(fInFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackBoomerDriver::OpenInput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } } gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackBoomerDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } cur_sample_format = fSampleFormat; if (ioctl(fInFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { jack_error("JackBoomerDriver::OpenInput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_format != fSampleFormat) { jack_info("JackBoomerDriver::OpenInput driver forced the sample format %ld", fSampleFormat); } cur_capture_channels = fCaptureChannels; if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { jack_error("JackBoomerDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_capture_channels != fCaptureChannels) { jack_info("JackBoomerDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); } cur_sample_rate = fEngineControl->fSampleRate; if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { jack_error("JackBoomerDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_rate != fEngineControl->fSampleRate) { jack_info("JackBoomerDriver::OpenInput driver forced the sample rate %ld", fEngineControl->fSampleRate); } // Just set the read size to the value we want... fInputBufferSize = fEngineControl->fBufferSize * fSampleSize * fCaptureChannels; fInputBuffer = (void*)calloc(fInputBufferSize, 1); assert(fInputBuffer); return 0; error: ::close(fInFD); return -1; } int JackBoomerDriver::OpenOutput() { int flags = 0; int gFragFormat; int cur_sample_format; int cur_playback_channels; jack_nframes_t cur_sample_rate; if (fPlaybackChannels == 0) fPlaybackChannels = 2; if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackBoomerDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } jack_log("JackBoomerDriver::OpenOutput output fOutFD = %d", fOutFD); if (fExcl) { if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } } gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } cur_sample_format = fSampleFormat; if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_format != fSampleFormat) { jack_info("JackBoomerDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); } cur_playback_channels = fPlaybackChannels; if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_playback_channels != fPlaybackChannels) { jack_info("JackBoomerDriver::OpenOutput driver forced the number of playback channels %ld", fPlaybackChannels); } cur_sample_rate = fEngineControl->fSampleRate; if (ioctl(fOutFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } if (cur_sample_rate != fEngineControl->fSampleRate) { jack_info("JackBoomerDriver::OpenInput driver forced the sample rate %ld", fEngineControl->fSampleRate); } // Just set the write size to the value we want... fOutputBufferSize = fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels; fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); assert(fOutputBuffer); return 0; error: ::close(fOutFD); return -1; } int JackBoomerDriver::Open(jack_nframes_t nframes, int user_nperiods, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool excl, bool monitor, const char* capture_driver_uid, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency, int bits, bool syncio) { // Generic JackAudioDriver Open if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { return -1; } else { if (!fEngineControl->fSyncMode) { jack_error("Cannot run in asynchronous mode, use the -S parameter for jackd"); return -1; } fRWMode |= ((capturing) ? kRead : 0); fRWMode |= ((playing) ? kWrite : 0); fBits = bits; fExcl = excl; fNperiods = (user_nperiods == 0) ? 1 : user_nperiods ; fSyncIO = syncio; #ifdef JACK_MONITOR // Force memory page in memset(&gCycleTable, 0, sizeof(gCycleTable)); #endif if (OpenAux() < 0) { Close(); return -1; } else { return 0; } } } int JackBoomerDriver::Close() { #ifdef JACK_MONITOR FILE* file = fopen("OSSProfiling.log", "w"); if (file) { jack_info("Writing OSS driver timing data...."); for (int i = 1; i < std::min(gCycleReadCount, gCycleWriteCount); i++) { int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); } fclose(file); } else { jack_error("JackBoomerDriver::Close : cannot open OSSProfiling.log file"); } file = fopen("TimingOSS.plot", "w"); if (file == NULL) { jack_error("JackBoomerDriver::Close cannot open TimingOSS.plot file"); } else { fprintf(file, "set grid\n"); fprintf(file, "set title \"OSS audio driver timing\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot \"OSSProfiling.log\" using 1 title \"Driver read wait\" with lines, \ \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); fprintf(file, "set output 'TimingOSS.pdf\n"); fprintf(file, "set terminal pdf\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"OSS audio driver timing\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot \"OSSProfiling.log\" using 1 title \"Driver read wait\" with lines, \ \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); fclose(file); } #endif int res = JackAudioDriver::Close(); CloseAux(); return res; } int JackBoomerDriver::OpenAux() { SetSampleFormat(); if ((fRWMode & kRead) && (OpenInput() < 0)) { return -1; } if ((fRWMode & kWrite) && (OpenOutput() < 0)) { return -1; } DisplayDeviceInfo(); return 0; } void JackBoomerDriver::CloseAux() { if (fRWMode & kRead && fInFD >= 0) { close(fInFD); fInFD = -1; } if (fRWMode & kWrite && fOutFD >= 0) { close(fOutFD); fOutFD = -1; } if (fInputBuffer) free(fInputBuffer); fInputBuffer = NULL; if (fOutputBuffer) free(fOutputBuffer); fOutputBuffer = NULL; } int JackBoomerDriver::Start() { jack_log("JackBoomerDriver::Start"); JackAudioDriver::Start(); // Input/output synchronisation if (fInFD >= 0 && fOutFD >= 0 && fSyncIO) { jack_log("JackBoomerDriver::Start sync input/output"); // Create and fill synch group int id; oss_syncgroup group; group.id = 0; group.mode = PCM_ENABLE_INPUT; if (ioctl(fInFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); group.mode = PCM_ENABLE_OUTPUT; if (ioctl(fOutFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); // Prefill output buffer : 2 fragments of silence as described in http://manuals.opensound.com/developer/synctest.c.html#LOC6 char* silence_buf = (char*)malloc(fFragmentSize); memset(silence_buf, 0, fFragmentSize); jack_log ("JackBoomerDriver::Start prefill size = %d", fFragmentSize); for (int i = 0; i < 2; i++) { ssize_t count = ::write(fOutFD, silence_buf, fFragmentSize); if (count < (int)fFragmentSize) { jack_error("JackBoomerDriver::Start error bytes written = %ld", count); } } free(silence_buf); // Start input/output in sync id = group.id; if (ioctl(fInFD, SNDCTL_DSP_SYNCSTART, &id) == -1) jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCSTART : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else if (fOutFD >= 0) { // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html memset(fOutputBuffer, 0, fOutputBufferSize); // Prefill ouput buffer for (int i = 0; i < fNperiods; i++) { ssize_t count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); if (count < (int)fOutputBufferSize) { jack_error("JackBoomerDriver::Start error bytes written = %ld", count); } } } // Start input thread only when needed if (fInFD >= 0) { if (fInputThread.StartSync() < 0) { jack_error("Cannot start input thread"); return -1; } } // Start output thread only when needed if (fOutFD >= 0) { if (fOutputThread.StartSync() < 0) { jack_error("Cannot start output thread"); return -1; } } return 0; } int JackBoomerDriver::Stop() { // Stop input thread only when needed if (fInFD >= 0) { fInputThread.Kill(); } // Stop output thread only when needed if (fOutFD >= 0) { fOutputThread.Kill(); } return 0; } bool JackBoomerDriver::JackBoomerDriverInput::Init() { if (fDriver->IsRealTime()) { jack_log("JackBoomerDriverInput::Init IsRealTime"); if (fDriver->fInputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); } else { set_threaded_log_function(); } } return true; } // TODO : better error handling bool JackBoomerDriver::JackBoomerDriverInput::Execute() { #ifdef JACK_MONITOR gCycleTable.fTable[gCycleReadCount].fBeforeRead = GetMicroSeconds(); #endif audio_errinfo ei_in; ssize_t count = ::read(fDriver->fInFD, fDriver->fInputBuffer, fDriver->fInputBufferSize); #ifdef JACK_MONITOR if (count > 0 && count != (int)fDriver->fInputBufferSize) jack_log("JackBoomerDriverInput::Execute count = %ld", count / (fDriver->fSampleSize * fDriver->fCaptureChannels)); gCycleTable.fTable[gCycleReadCount].fAfterRead = GetMicroSeconds(); #endif // XRun detection if (ioctl(fDriver->fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { if (ei_in.rec_overruns > 0 ) { jack_error("JackBoomerDriverInput::Execute overruns"); jack_time_t cur_time = GetMicroSeconds(); fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... } if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); } } if (count < 0) { jack_log("JackBoomerDriverInput::Execute error = %s", strerror(errno)); } else if (count < (int)fDriver->fInputBufferSize) { jack_error("JackBoomerDriverInput::Execute error bytes read = %ld", count); } else { // Keep begin cycle time fDriver->CycleTakeBeginTime(); for (int i = 0; i < fDriver->fCaptureChannels; i++) { if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fCapturePortList[i]) > 0) { CopyAndConvertIn(fDriver->GetInputBuffer(i), fDriver->fInputBuffer, fDriver->fEngineControl->fBufferSize, i, fDriver->fCaptureChannels * fDriver->fSampleSize, fDriver->fBits); } } #ifdef JACK_MONITOR gCycleTable.fTable[gCycleReadCount].fAfterReadConvert = GetMicroSeconds(); gCycleReadCount = (gCycleReadCount == CYCLE_POINTS - 1) ? gCycleReadCount: gCycleReadCount + 1; #endif } // Duplex : sync with write thread if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { fDriver->SynchronizeRead(); } else { // Otherwise direct process fDriver->Process(); } return true; } bool JackBoomerDriver::JackBoomerDriverOutput::Init() { if (fDriver->IsRealTime()) { jack_log("JackBoomerDriverOutput::Init IsRealTime"); if (fDriver->fOutputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); } else { set_threaded_log_function(); } } int delay; if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { jack_error("JackBoomerDriverOutput::Init error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); } delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; jack_info("JackBoomerDriverOutput::Init output latency frames = %ld", delay); return true; } // TODO : better error handling bool JackBoomerDriver::JackBoomerDriverOutput::Execute() { memset(fDriver->fOutputBuffer, 0, fDriver->fOutputBufferSize); #ifdef JACK_MONITOR gCycleTable.fTable[gCycleWriteCount].fBeforeWriteConvert = GetMicroSeconds(); #endif for (int i = 0; i < fDriver->fPlaybackChannels; i++) { if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fPlaybackPortList[i]) > 0) { CopyAndConvertOut(fDriver->fOutputBuffer, fDriver->GetOutputBuffer(i), fDriver->fEngineControl->fBufferSize, i, fDriver->fPlaybackChannels * fDriver->fSampleSize, fDriver->fBits); } } #ifdef JACK_MONITOR gCycleTable.fTable[gCycleWriteCount].fBeforeWrite = GetMicroSeconds(); #endif ssize_t count = ::write(fDriver->fOutFD, fDriver->fOutputBuffer, fDriver->fOutputBufferSize); #ifdef JACK_MONITOR if (count > 0 && count != (int)fDriver->fOutputBufferSize) jack_log("JackBoomerDriverOutput::Execute count = %ld", count / (fDriver->fSampleSize * fDriver->fPlaybackChannels)); gCycleTable.fTable[gCycleWriteCount].fAfterWrite = GetMicroSeconds(); gCycleWriteCount = (gCycleWriteCount == CYCLE_POINTS - 1) ? gCycleWriteCount: gCycleWriteCount + 1; #endif // XRun detection audio_errinfo ei_out; if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETERROR, &ei_out) == 0) { if (ei_out.play_underruns > 0) { jack_error("JackBoomerDriverOutput::Execute underruns"); jack_time_t cur_time = GetMicroSeconds(); fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... } if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); } } if (count < 0) { jack_log("JackBoomerDriverOutput::Execute error = %s", strerror(errno)); } else if (count < (int)fDriver->fOutputBufferSize) { jack_error("JackBoomerDriverOutput::Execute error bytes written = %ld", count); } // Duplex : sync with read thread if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { fDriver->SynchronizeWrite(); } else { // Otherwise direct process fDriver->CycleTakeBeginTime(); fDriver->Process(); } return true; } void JackBoomerDriver::SynchronizeRead() { sem_wait(&fWriteSema); Process(); sem_post(&fReadSema); } void JackBoomerDriver::SynchronizeWrite() { sem_post(&fWriteSema); sem_wait(&fReadSema); } int JackBoomerDriver::SetBufferSize(jack_nframes_t buffer_size) { CloseAux(); JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails return OpenAux(); } } // end of namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("boomer", JackDriverMaster, "Boomer/OSS API based audio backend", &filler); value.ui = OSS_DRIVER_DEF_FS; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = OSS_DRIVER_DEF_BLKSIZE; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = OSS_DRIVER_DEF_NPERIODS; jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods to prefill output buffer", NULL); value.i = OSS_DRIVER_DEF_BITS; jack_driver_descriptor_add_parameter(desc, &filler, "wordlength", 'w', JackDriverParamInt, &value, NULL, "Word length", NULL); value.ui = OSS_DRIVER_DEF_INS; jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Capture channels", NULL); value.ui = OSS_DRIVER_DEF_OUTS; jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Playback channels", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "excl", 'e', JackDriverParamBool, &value, NULL, "Exclusif (O_EXCL) access mode", NULL); strcpy(value.str, OSS_DRIVER_DEF_DEV); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input device", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Output device", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "OSS device name", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "sync-io", 'S', JackDriverParamBool, &value, NULL, "In duplex mode, synchronize input and output", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { int bits = OSS_DRIVER_DEF_BITS; jack_nframes_t srate = OSS_DRIVER_DEF_FS; jack_nframes_t frames_per_interrupt = OSS_DRIVER_DEF_BLKSIZE; const char* capture_pcm_name = OSS_DRIVER_DEF_DEV; const char* playback_pcm_name = OSS_DRIVER_DEF_DEV; bool capture = false; bool playback = false; int chan_in = 0; int chan_out = 0; bool monitor = false; bool excl = false; bool syncio = false; unsigned int nperiods = OSS_DRIVER_DEF_NPERIODS; const JSList *node; const jack_driver_param_t *param; jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t *)node->data; switch (param->character) { case 'r': srate = param->value.ui; break; case 'p': frames_per_interrupt = (unsigned int)param->value.ui; break; case 'n': nperiods = (unsigned int)param->value.ui; break; case 'w': bits = param->value.i; break; case 'i': chan_in = (int)param->value.ui; break; case 'o': chan_out = (int)param->value.ui; break; case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { capture_pcm_name = param->value.str; } break; case 'P': playback = true; if (strcmp(param->value.str, "none") != 0) { playback_pcm_name = param->value.str; } break; case 'd': playback_pcm_name = param->value.str; capture_pcm_name = param->value.str; break; case 'e': excl = true; break; case 'I': systemic_input_latency = param->value.ui; break; case 'O': systemic_output_latency = param->value.ui; break; case 'S': syncio = true; break; } } // duplex is the default if (!capture && !playback) { capture = true; playback = true; } Jack::JackBoomerDriver* boomer_driver = new Jack::JackBoomerDriver("system", "boomer", engine, table); // Special open for Boomer driver... if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, syncio) == 0) { return boomer_driver; } else { delete boomer_driver; // Delete the driver return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/solaris/oss/JackOSSDriver.h0000644000000000000000000000631413214314510016406 0ustar rootroot/* Copyright (C) 2003-2007 Jussi Laako Copyright (C) 2008 Grame & RTL 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackOSSDriver__ #define __JackOSSDriver__ #include "JackAudioDriver.h" namespace Jack { typedef jack_default_audio_sample_t jack_sample_t; #define OSS_DRIVER_DEF_DEV "/dev/dsp" #define OSS_DRIVER_DEF_FS 48000 #define OSS_DRIVER_DEF_BLKSIZE 1024 #define OSS_DRIVER_DEF_NPERIODS 1 #define OSS_DRIVER_DEF_BITS 16 #define OSS_DRIVER_DEF_INS 2 #define OSS_DRIVER_DEF_OUTS 2 /*! \brief The OSS driver. */ class JackOSSDriver : public JackAudioDriver { enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; private: int fInFD; int fOutFD; int fBits; int fSampleFormat; int fNperiods; unsigned int fSampleSize; int fRWMode; bool fExcl; bool fIgnoreHW; unsigned int fInputBufferSize; unsigned int fOutputBufferSize; void* fInputBuffer; void* fOutputBuffer; bool fFirstCycle; int OpenInput(); int OpenOutput(); int OpenAux(); void CloseAux(); void SetSampleFormat(); void DisplayDeviceInfo(); // Redefining since timing for CPU load is specific int ProcessSync(); public: JackOSSDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), fInFD(-1), fOutFD(-1), fBits(0), fSampleFormat(0), fNperiods(0), fRWMode(0), fExcl(false), fIgnoreHW(true), fInputBufferSize(0), fOutputBufferSize(0), fInputBuffer(NULL), fOutputBuffer(NULL), fFirstCycle(true) {} virtual ~JackOSSDriver() {} int Open(jack_nframes_t frames_per_cycle, int user_nperiods, jack_nframes_t rate, bool capturing, bool playing, int chan_in, int chan_out, bool vmix, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, int bits, bool ignorehwbuf); int Close(); int Read(); int Write(); // BufferSize can be changed bool IsFixedBufferSize() { return false; } int SetBufferSize(jack_nframes_t buffer_size); }; } // end of namespace #endif 1.9.12~dfsg/solaris/oss/JackBoomerDriver.h0000644000000000000000000000756313214314510017174 0ustar rootroot/* Copyright (C) 2009 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackBoomerDriver__ #define __JackBoomerDriver__ #include "JackAudioDriver.h" #include "JackPlatformPlug.h" #include "ringbuffer.h" #include namespace Jack { typedef jack_default_audio_sample_t jack_sample_t; #define OSS_DRIVER_DEF_DEV "/dev/dsp" #define OSS_DRIVER_DEF_FS 48000 #define OSS_DRIVER_DEF_BLKSIZE 1024 #define OSS_DRIVER_DEF_NPERIODS 1 #define OSS_DRIVER_DEF_BITS 16 #define OSS_DRIVER_DEF_INS 2 #define OSS_DRIVER_DEF_OUTS 2 /*! \brief The Boomer driver. */ class JackBoomerDriver : public JackAudioDriver { enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; private: class JackBoomerDriverInput : public JackRunnableInterface { private: JackBoomerDriver* fDriver; public: JackBoomerDriverInput(JackBoomerDriver* driver): fDriver(driver) {} ~JackBoomerDriverInput() {} bool Init(); bool Execute(); }; class JackBoomerDriverOutput : public JackRunnableInterface { private: JackBoomerDriver* fDriver; public: JackBoomerDriverOutput(JackBoomerDriver* driver): fDriver(driver) {} ~JackBoomerDriverOutput() {} bool Init(); bool Execute(); }; int fInFD; int fOutFD; int fBits; int fSampleFormat; int fNperiods; unsigned int fSampleSize; unsigned int fFragmentSize; int fRWMode; bool fExcl; bool fSyncIO; unsigned int fInputBufferSize; unsigned int fOutputBufferSize; void* fInputBuffer; void* fOutputBuffer; sem_t fReadSema; sem_t fWriteSema; JackThread fInputThread; JackThread fOutputThread; JackBoomerDriverInput fInputHandler; JackBoomerDriverOutput fOutputHandler; int OpenInput(); int OpenOutput(); int OpenAux(); void CloseAux(); void SetSampleFormat(); void DisplayDeviceInfo(); void SynchronizeRead(); void SynchronizeWrite(); public: JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); virtual ~JackBoomerDriver(); int Open(jack_nframes_t frames_per_cycle, int user_nperiods, jack_nframes_t rate, bool capturing, bool playing, int chan_in, int chan_out, bool excl, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, int bits, bool syncio); int Close(); int Start(); int Stop(); // BufferSize can be changed bool IsFixedBufferSize() { return false; } int SetBufferSize(jack_nframes_t buffer_size); }; } // end of namespace #endif 1.9.12~dfsg/solaris/oss/JackOSSAdapter.h0000644000000000000000000000520713214314510016533 0ustar rootroot/* Copyright (C) 2008 Grame & RTL 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackOSSAdapter__ #define __JackOSSAdapter__ #include #include #include #include "JackAudioAdapterInterface.h" #include "JackPlatformPlug.h" #include "JackError.h" #include "jack.h" #include "jslist.h" namespace Jack { typedef jack_default_audio_sample_t jack_sample_t; #define OSS_DRIVER_DEF_DEV "/dev/dsp" #define OSS_DRIVER_DEF_FS 48000 #define OSS_DRIVER_DEF_BLKSIZE 1024 #define OSS_DRIVER_DEF_NPERIODS 2 #define OSS_DRIVER_DEF_BITS 16 #define OSS_DRIVER_DEF_INS 2 #define OSS_DRIVER_DEF_OUTS 2 /*! \brief The OSS adapter. */ class JackOSSAdapter : public JackAudioAdapterInterface, public JackRunnableInterface { enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; private: JackThread fThread; char fCaptureDriverName[JACK_CLIENT_NAME_SIZE+1]; char fPlaybackDriverName[JACK_CLIENT_NAME_SIZE+1]; int fInFD; int fOutFD; int fBits; int fSampleFormat; int fNperiods; unsigned int fSampleSize; int fRWMode; bool fIgnoreHW; bool fExcl; unsigned int fInputBufferSize; unsigned int fOutputBufferSize; void* fInputBuffer; void* fOutputBuffer; float** fInputSampleBuffer; float** fOutputSampleBuffer; bool fFirstCycle; int OpenInput(); int OpenOutput(); void CloseAux(); void SetSampleFormat(); void DisplayDeviceInfo(); public: JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackOSSAdapter() {} int Open(); int Close(); int Read(); int Write(); int SetBufferSize(jack_nframes_t buffer_size); bool Execute(); }; } #ifdef __cplusplus extern "C" { #endif #include "JackCompilerDeps.h" #include "driver_interface.h" SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor(); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/solaris/JackSolarisTime.c0000644000000000000000000000227213214314510016207 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackTime.h" #include "JackTypes.h" #include #include SERVER_EXPORT void JackSleep(long usec) { usleep(usec); } SERVER_EXPORT void InitTime() {} SERVER_EXPORT void EndTime() {} SERVER_EXPORT jack_time_t GetMicroSeconds(void) { return (jack_time_t)(gethrtime() / 1000); } void SetClockSource(jack_timer_type_t source) {} const char* ClockSourceName(jack_timer_type_t source) { return ""; } 1.9.12~dfsg/linux/0000755000000000000000000000000013214314510012477 5ustar rootroot1.9.12~dfsg/linux/alsarawmidi/0000755000000000000000000000000013214314510014774 5ustar rootroot1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiOutputPort.h0000644000000000000000000000343313214314510022024 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackALSARawMidiOutputPort__ #define __JackALSARawMidiOutputPort__ #include "JackALSARawMidiPort.h" #include "JackALSARawMidiSendQueue.h" #include "JackMidiAsyncQueue.h" #include "JackMidiBufferReadQueue.h" #include "JackMidiRawOutputWriteQueue.h" namespace Jack { class JackALSARawMidiOutputPort: public JackALSARawMidiPort { private: jack_midi_event_t *alsa_event; JackMidiRawOutputWriteQueue *raw_queue; JackMidiBufferReadQueue *read_queue; JackALSARawMidiSendQueue *send_queue; JackMidiAsyncQueue *thread_queue; public: JackALSARawMidiOutputPort(snd_rawmidi_info_t *info, size_t index, size_t max_bytes_per_poll=3, size_t max_bytes=4096, size_t max_messages=1024); ~JackALSARawMidiOutputPort(); bool ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); bool ProcessPollEvents(bool handle_output, bool timeout, jack_nframes_t *frame); }; } #endif 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiInputPort.h0000644000000000000000000000332113214314510021617 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackALSARawMidiInputPort__ #define __JackALSARawMidiInputPort__ #include "JackALSARawMidiPort.h" #include "JackALSARawMidiReceiveQueue.h" #include "JackMidiAsyncQueue.h" #include "JackMidiBufferWriteQueue.h" #include "JackMidiRawInputWriteQueue.h" namespace Jack { class JackALSARawMidiInputPort: public JackALSARawMidiPort { private: jack_midi_event_t *alsa_event; jack_midi_event_t *jack_event; JackMidiRawInputWriteQueue *raw_queue; JackALSARawMidiReceiveQueue *receive_queue; JackMidiAsyncQueue *thread_queue; JackMidiBufferWriteQueue *write_queue; public: JackALSARawMidiInputPort(snd_rawmidi_info_t *info, size_t index, size_t max_bytes=4096, size_t max_messages=1024); ~JackALSARawMidiInputPort(); bool ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); bool ProcessPollEvents(jack_nframes_t current_frame); }; } #endif 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiPort.cpp0000644000000000000000000001707613214314510021146 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "JackALSARawMidiPort.h" #include "JackALSARawMidiUtil.h" #include "JackError.h" using Jack::JackALSARawMidiPort; JackALSARawMidiPort::JackALSARawMidiPort(snd_rawmidi_info_t *info, size_t index, unsigned short io_mask) { int card = snd_rawmidi_info_get_card(info); unsigned int device = snd_rawmidi_info_get_device(info); unsigned int subdevice = snd_rawmidi_info_get_subdevice(info); char device_id[32]; snprintf(device_id, sizeof(device_id), "hw:%d,%d,%d", card, device, subdevice); const char *alias_suffix; const char *error_message; snd_rawmidi_t **in; const char *name_prefix; snd_rawmidi_t **out; if (snd_rawmidi_info_get_stream(info) == SND_RAWMIDI_STREAM_OUTPUT) { alias_suffix = "out"; in = 0; name_prefix = "system:midi_playback_"; out = &rawmidi; } else { alias_suffix = "in"; in = &rawmidi; name_prefix = "system:midi_capture_"; out = 0; } const char *func; int code = snd_rawmidi_open(in, out, device_id, SND_RAWMIDI_NONBLOCK); if (code) { error_message = snd_strerror(code); func = "snd_rawmidi_open"; goto handle_error; } snd_rawmidi_params_t *params; code = snd_rawmidi_params_malloc(¶ms); if (code) { error_message = snd_strerror(code); func = "snd_rawmidi_params_malloc"; goto close; } code = snd_rawmidi_params_current(rawmidi, params); if (code) { error_message = snd_strerror(code); func = "snd_rawmidi_params_current"; goto free_params; } code = snd_rawmidi_params_set_avail_min(rawmidi, params, 1); if (code) { error_message = snd_strerror(code); func = "snd_rawmidi_params_set_avail_min"; goto free_params; } // Minimum buffer size allowed by ALSA code = snd_rawmidi_params_set_buffer_size(rawmidi, params, 32); if (code) { error_message = snd_strerror(code); func = "snd_rawmidi_params_set_buffer_size"; goto free_params; } code = snd_rawmidi_params_set_no_active_sensing(rawmidi, params, 1); if (code) { error_message = snd_strerror(code); func = "snd_rawmidi_params_set_no_active_sensing"; goto free_params; } code = snd_rawmidi_params(rawmidi, params); if (code) { error_message = snd_strerror(code); func = "snd_rawmidi_params"; goto free_params; } snd_rawmidi_params_free(params); alsa_poll_fd_count = snd_rawmidi_poll_descriptors_count(rawmidi); if (! alsa_poll_fd_count) { error_message = "returned '0' count for poll descriptors"; func = "snd_rawmidi_poll_descriptors_count"; goto close; } try { CreateNonBlockingPipe(fds); } catch (std::exception e) { error_message = e.what(); func = "CreateNonBlockingPipe"; goto close; } snprintf(alias, sizeof(alias), "system:%d-%d %s %d %s", card + 1, device + 1, snd_rawmidi_info_get_name(info), subdevice + 1, alias_suffix); snprintf(name, sizeof(name), "%s%zu", name_prefix, index + 1); this->io_mask = io_mask; return; free_params: snd_rawmidi_params_free(params); close: snd_rawmidi_close(rawmidi); handle_error: throw std::runtime_error(std::string(func) + ": " + error_message); } JackALSARawMidiPort::~JackALSARawMidiPort() { DestroyNonBlockingPipe(fds); if (rawmidi) { int code = snd_rawmidi_close(rawmidi); if (code) { jack_error("JackALSARawMidiPort::~JackALSARawMidiPort - " "snd_rawmidi_close: %s", snd_strerror(code)); } rawmidi = 0; } } const char * JackALSARawMidiPort::GetAlias() { return alias; } int JackALSARawMidiPort::GetIOPollEvent() { unsigned short events; int code = snd_rawmidi_poll_descriptors_revents(rawmidi, alsa_poll_fds, alsa_poll_fd_count, &events); if (code) { jack_error("JackALSARawMidiPort::GetIOPollEvents - " "snd_rawmidi_poll_descriptors_revents: %s", snd_strerror(code)); return -1; } if (events & POLLNVAL) { jack_error("JackALSARawMidiPort::GetIOPollEvents - the file " "descriptor is invalid."); return -1; } if (events & POLLERR) { jack_error("JackALSARawMidiPort::GetIOPollEvents - an error has " "occurred on the device or stream."); return -1; } return (events & io_mask) ? 1 : 0; } const char * JackALSARawMidiPort::GetName() { return name; } int JackALSARawMidiPort::GetPollDescriptorCount() { return alsa_poll_fd_count + 1; } int JackALSARawMidiPort::GetQueuePollEvent() { unsigned short events = queue_poll_fd->revents; if (events & POLLNVAL) { jack_error("JackALSARawMidiPort::GetQueuePollEvents - the file " "descriptor is invalid."); return -1; } if (events & POLLERR) { jack_error("JackALSARawMidiPort::GetQueuePollEvents - an error has " "occurred on the device or stream."); return -1; } int event = events & POLLIN ? 1 : 0; if (event) { char c; ssize_t result = read(fds[0], &c, 1); assert(result); if (result < 0) { jack_error("JackALSARawMidiPort::GetQueuePollEvents - error " "reading a byte from the pipe file descriptor: %s", strerror(errno)); return -1; } } return event; } void JackALSARawMidiPort::PopulatePollDescriptors(struct pollfd *poll_fd) { alsa_poll_fds = poll_fd + 1; assert(snd_rawmidi_poll_descriptors(rawmidi, alsa_poll_fds, alsa_poll_fd_count) == alsa_poll_fd_count); queue_poll_fd = poll_fd; queue_poll_fd->events = POLLERR | POLLIN | POLLNVAL; queue_poll_fd->fd = fds[0]; SetIOEventsEnabled(true); } void JackALSARawMidiPort::SetIOEventsEnabled(bool enabled) { unsigned short mask = POLLNVAL | POLLERR | (enabled ? io_mask : 0); for (int i = 0; i < alsa_poll_fd_count; i++) { (alsa_poll_fds + i)->events = mask; } } bool JackALSARawMidiPort::TriggerQueueEvent() { char c; ssize_t result = write(fds[1], &c, 1); assert(result <= 1); switch (result) { case 1: return true; case 0: jack_error("JackALSARawMidiPort::TriggerQueueEvent - error writing a " "byte to the pipe file descriptor: %s", strerror(errno)); break; default: jack_error("JackALSARawMidiPort::TriggerQueueEvent - couldn't write a " "byte to the pipe file descriptor."); } return false; } 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp0000644000000000000000000001200313214314510022350 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackALSARawMidiOutputPort.h" #include "JackError.h" using Jack::JackALSARawMidiOutputPort; JackALSARawMidiOutputPort::JackALSARawMidiOutputPort(snd_rawmidi_info_t *info, size_t index, size_t max_bytes_per_poll, size_t max_bytes, size_t max_messages): JackALSARawMidiPort(info, index, POLLOUT) { alsa_event = 0; read_queue = new JackMidiBufferReadQueue(); std::auto_ptr read_ptr(read_queue); send_queue = new JackALSARawMidiSendQueue(rawmidi, max_bytes_per_poll); std::auto_ptr send_ptr(send_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); std::auto_ptr thread_ptr(thread_queue); raw_queue = new JackMidiRawOutputWriteQueue(send_queue, max_bytes, max_messages, max_messages); thread_ptr.release(); send_ptr.release(); read_ptr.release(); } JackALSARawMidiOutputPort::~JackALSARawMidiOutputPort() { delete raw_queue; delete read_queue; delete send_queue; delete thread_queue; } bool JackALSARawMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { read_queue->ResetMidiBuffer(port_buffer); bool enqueued = false; for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; event = read_queue->DequeueEvent()) { switch (thread_queue->EnqueueEvent(event, frames)) { case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackALSARawMidiOutputPort::ProcessJack - The thread " "queue doesn't have enough room to enqueue a %d-byte " "event. Dropping event.", event->size); continue; case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackALSARawMidiOutputPort::ProcessJack - The thread " "queue is too small to enqueue a %d-byte event. " "Dropping event.", event->size); continue; default: enqueued = true; } } return enqueued ? TriggerQueueEvent() : true; } bool JackALSARawMidiOutputPort::ProcessPollEvents(bool handle_output, bool timeout, jack_nframes_t *frame) { int io_event; int queue_event; send_queue->ResetPollByteCount(); if (! handle_output) { assert(timeout); goto process_raw_queue; } io_event = GetIOPollEvent(); if (io_event == -1) { return false; } queue_event = GetQueuePollEvent(); if (queue_event == -1) { return false; } if (io_event || timeout) { process_raw_queue: // We call the 'Process' event early because there are events waiting // to be processed that either need to be sent now, or before now. raw_queue->Process(); } else if (! queue_event) { return true; } if (! alsa_event) { alsa_event = thread_queue->DequeueEvent(); } for (; alsa_event; alsa_event = thread_queue->DequeueEvent()) { switch (raw_queue->EnqueueEvent(alsa_event)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackALSARawMidiOutputPort::ProcessQueues - The raw " "output queue couldn't enqueue a %d-byte event. " "Dropping event.", alsa_event->size); // Fallthrough on purpose. case JackMidiWriteQueue::OK: continue; default: ; } // Try to free up some space by processing events early. *frame = raw_queue->Process(); switch (raw_queue->EnqueueEvent(alsa_event)) { case JackMidiWriteQueue::BUFFER_FULL: goto set_io_events; case JackMidiWriteQueue::BUFFER_TOO_SMALL: // This shouldn't happen. assert(false); default: ; } } *frame = raw_queue->Process(); set_io_events: bool blocked = send_queue->IsBlocked(); SetIOEventsEnabled(blocked); if (blocked) { *frame = 0; } return true; } 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiReceiveQueue.h0000644000000000000000000000245513214314510022251 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackALSARawMidiReceiveQueue__ #define __JackALSARawMidiReceiveQueue__ #include #include "JackMidiReceiveQueue.h" namespace Jack { class JackALSARawMidiReceiveQueue: public JackMidiReceiveQueue { private: jack_midi_data_t *buffer; size_t buffer_size; jack_midi_event_t event; snd_rawmidi_t *rawmidi; public: JackALSARawMidiReceiveQueue(snd_rawmidi_t *rawmidi, size_t buffer_size=4096); ~JackALSARawMidiReceiveQueue(); jack_midi_event_t * DequeueEvent(); }; } #endif 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiDriver.cpp0000644000000000000000000005402713214314510021452 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include "JackALSARawMidiDriver.h" #include "JackALSARawMidiUtil.h" #include "JackEngineControl.h" #include "JackError.h" #include "JackMidiUtil.h" #include "driver_interface.h" using Jack::JackALSARawMidiDriver; JackALSARawMidiDriver::JackALSARawMidiDriver(const char *name, const char *alias, JackLockedEngine *engine, JackSynchro *table): JackMidiDriver(name, alias, engine, table) { thread = new JackThread(this); fds[0] = -1; fds[1] = -1; input_ports = 0; output_ports = 0; output_port_timeouts = 0; poll_fds = 0; } JackALSARawMidiDriver::~JackALSARawMidiDriver() { delete thread; } int JackALSARawMidiDriver::Attach() { const char *alias; jack_nframes_t buffer_size = fEngineControl->fBufferSize; jack_port_id_t index; jack_nframes_t latency = buffer_size; jack_latency_range_t latency_range; const char *name; JackPort *port; latency_range.max = latency; latency_range.min = latency; for (int i = 0; i < fCaptureChannels; i++) { JackALSARawMidiInputPort *input_port = input_ports[i]; name = input_port->GetName(); fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, buffer_size, &index); if (index == NO_PORT) { jack_error("JackALSARawMidiDriver::Attach - cannot register input " "port with name '%s'.", name); // XX: Do we need to deallocate ports? return -1; } alias = input_port->GetAlias(); port = fGraphManager->GetPort(index); port->SetAlias(alias); port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[i] = index; jack_info("JackALSARawMidiDriver::Attach - input port registered " "(name='%s', alias='%s').", name, alias); } if (! fEngineControl->fSyncMode) { latency += buffer_size; latency_range.max = latency; latency_range.min = latency; } for (int i = 0; i < fPlaybackChannels; i++) { JackALSARawMidiOutputPort *output_port = output_ports[i]; name = output_port->GetName(); fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, buffer_size, &index); if (index == NO_PORT) { jack_error("JackALSARawMidiDriver::Attach - cannot register " "output port with name '%s'.", name); // XX: Do we need to deallocate ports? return -1; } alias = output_port->GetAlias(); port = fGraphManager->GetPort(index); port->SetAlias(alias); port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[i] = index; jack_info("JackALSARawMidiDriver::Attach - output port registered " "(name='%s', alias='%s').", name, alias); } return 0; } int JackALSARawMidiDriver::Close() { // Generic MIDI driver close int result = JackMidiDriver::Close(); if (input_ports) { for (int i = 0; i < fCaptureChannels; i++) { delete input_ports[i]; } delete[] input_ports; input_ports = 0; } if (output_ports) { for (int i = 0; i < fPlaybackChannels; i++) { delete output_ports[i]; } delete[] output_ports; output_ports = 0; } return result; } bool JackALSARawMidiDriver::Execute() { jack_nframes_t timeout_frame = 0; for (;;) { struct timespec timeout; struct timespec *timeout_ptr; if (! timeout_frame) { timeout_ptr = 0; } else { // The timeout value is relative to the time that // 'GetMicroSeconds()' is called, not the time that 'poll()' is // called. This means that the amount of time that passes between // 'GetMicroSeconds()' and 'ppoll()' is time that will be lost // while waiting for 'poll() to timeout. // // I tried to replace the timeout with a 'timerfd' with absolute // times, but, strangely, it actually slowed things down, and made // the code a lot more complicated. // // I wonder about using the 'epoll' interface instead of 'ppoll()'. // The problem with the 'epoll' interface is that the timeout // resolution of 'epoll_wait()' is set in milliseconds. We need // microsecond resolution. Without microsecond resolution, we // impose the same jitter as USB MIDI. // // Another problem is that 'ppoll()' returns later than the wait // time. The problem can be minimized with high precision timers. timeout_ptr = &timeout; jack_time_t next_time = GetTimeFromFrames(timeout_frame); jack_time_t now = GetMicroSeconds(); if (next_time <= now) { timeout.tv_sec = 0; timeout.tv_nsec = 0; } else { jack_time_t wait_time = next_time - now; timeout.tv_sec = wait_time / 1000000; timeout.tv_nsec = (wait_time % 1000000) * 1000; } } int poll_result = ppoll(poll_fds, poll_fd_count, timeout_ptr, 0); // Getting the current frame value here allows us to use it for // incoming MIDI bytes. This makes sense, as the data has already // arrived at this point. jack_nframes_t current_frame = GetCurrentFrame(); if (poll_result == -1) { if (errno == EINTR) { continue; } jack_error("JackALSARawMidiDriver::Execute - poll error: %s", strerror(errno)); break; } jack_nframes_t port_timeout; timeout_frame = 0; if (! poll_result) { // No I/O events occurred. So, only handle timeout events on // output ports. for (int i = 0; i < fPlaybackChannels; i++) { port_timeout = output_port_timeouts[i]; if (port_timeout && (port_timeout <= current_frame)) { if (! output_ports[i]->ProcessPollEvents(false, true, &port_timeout)) { jack_error("JackALSARawMidiDriver::Execute - a fatal " "error occurred while processing ALSA " "output events."); goto cleanup; } output_port_timeouts[i] = port_timeout; } if (port_timeout && ((! timeout_frame) || (port_timeout < timeout_frame))) { timeout_frame = port_timeout; } } continue; } // See if it's time to shutdown. unsigned short revents = poll_fds[0].revents; if (revents) { if (revents & (~ POLLHUP)) { jack_error("JackALSARawMidiDriver::Execute - unexpected poll " "event on pipe file descriptor."); } break; } // Handle I/O events *and* timeout events on output ports. for (int i = 0; i < fPlaybackChannels; i++) { port_timeout = output_port_timeouts[i]; bool timeout = port_timeout && (port_timeout <= current_frame); if (! output_ports[i]->ProcessPollEvents(true, timeout, &port_timeout)) { jack_error("JackALSARawMidiDriver::Execute - a fatal error " "occurred while processing ALSA output events."); goto cleanup; } output_port_timeouts[i] = port_timeout; if (port_timeout && ((! timeout_frame) || (port_timeout < timeout_frame))) { timeout_frame = port_timeout; } } // Handle I/O events on input ports. We handle these last because we // already computed the arrival time above, and will impose a delay on // the events by 'period-size' frames anyway, which gives us a bit of // borrowed time. for (int i = 0; i < fCaptureChannels; i++) { if (! input_ports[i]->ProcessPollEvents(current_frame)) { jack_error("JackALSARawMidiDriver::Execute - a fatal error " "occurred while processing ALSA input events."); goto cleanup; } } } cleanup: close(fds[0]); fds[0] = -1; jack_info("JackALSARawMidiDriver::Execute - ALSA thread exiting."); return false; } void JackALSARawMidiDriver:: FreeDeviceInfo(std::vector *in_info_list, std::vector *out_info_list) { size_t length = in_info_list->size(); for (size_t i = 0; i < length; i++) { snd_rawmidi_info_free(in_info_list->at(i)); } length = out_info_list->size(); for (size_t i = 0; i < length; i++) { snd_rawmidi_info_free(out_info_list->at(i)); } } void JackALSARawMidiDriver:: GetDeviceInfo(snd_ctl_t *control, snd_rawmidi_info_t *info, std::vector *info_list) { snd_rawmidi_info_set_subdevice(info, 0); int code = snd_ctl_rawmidi_info(control, info); if (code) { if (code != -ENOENT) { HandleALSAError("GetDeviceInfo", "snd_ctl_rawmidi_info", code); } return; } unsigned int count = snd_rawmidi_info_get_subdevices_count(info); for (unsigned int i = 0; i < count; i++) { snd_rawmidi_info_set_subdevice(info, i); int code = snd_ctl_rawmidi_info(control, info); if (code) { HandleALSAError("GetDeviceInfo", "snd_ctl_rawmidi_info", code); continue; } snd_rawmidi_info_t *info_copy; code = snd_rawmidi_info_malloc(&info_copy); if (code) { HandleALSAError("GetDeviceInfo", "snd_rawmidi_info_malloc", code); continue; } snd_rawmidi_info_copy(info_copy, info); try { info_list->push_back(info_copy); } catch (std::bad_alloc &e) { snd_rawmidi_info_free(info_copy); jack_error("JackALSARawMidiDriver::GetDeviceInfo - " "std::vector::push_back: %s", e.what()); } } } void JackALSARawMidiDriver::HandleALSAError(const char *driver_func, const char *alsa_func, int code) { jack_error("JackALSARawMidiDriver::%s - %s: %s", driver_func, alsa_func, snd_strerror(code)); } bool JackALSARawMidiDriver::Init() { set_threaded_log_function(); if (thread->AcquireSelfRealTime(fEngineControl->fServerPriority + 1)) { jack_error("JackALSARawMidiDriver::Init - could not acquire realtime " "scheduling. Continuing anyway."); } return true; } int JackALSARawMidiDriver::Open(bool capturing, bool playing, int in_channels, int out_channels, bool monitor, const char *capture_driver_name, const char *playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { snd_rawmidi_info_t *info; int code = snd_rawmidi_info_malloc(&info); if (code) { HandleALSAError("Open", "snd_rawmidi_info_malloc", code); return -1; } std::vector in_info_list; std::vector out_info_list; for (int card = -1;;) { int code = snd_card_next(&card); if (code) { HandleALSAError("Open", "snd_card_next", code); continue; } if (card == -1) { break; } char name[32]; snprintf(name, sizeof(name), "hw:%d", card); snd_ctl_t *control; code = snd_ctl_open(&control, name, SND_CTL_NONBLOCK); if (code) { HandleALSAError("Open", "snd_ctl_open", code); continue; } for (int device = -1;;) { code = snd_ctl_rawmidi_next_device(control, &device); if (code) { HandleALSAError("Open", "snd_ctl_rawmidi_next_device", code); continue; } if (device == -1) { break; } snd_rawmidi_info_set_device(info, device); snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); GetDeviceInfo(control, info, &in_info_list); snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); GetDeviceInfo(control, info, &out_info_list); } snd_ctl_close(control); } snd_rawmidi_info_free(info); size_t potential_inputs = in_info_list.size(); size_t potential_outputs = out_info_list.size(); if (! (potential_inputs || potential_outputs)) { jack_error("JackALSARawMidiDriver::Open - no ALSA raw MIDI input or " "output ports found."); FreeDeviceInfo(&in_info_list, &out_info_list); return -1; } size_t num_inputs = 0; size_t num_outputs = 0; if (potential_inputs) { try { input_ports = new JackALSARawMidiInputPort *[potential_inputs]; } catch (std::exception e) { jack_error("JackALSARawMidiDriver::Open - while creating input " "port array: %s", e.what()); FreeDeviceInfo(&in_info_list, &out_info_list); return -1; } } if (potential_outputs) { try { output_ports = new JackALSARawMidiOutputPort *[potential_outputs]; } catch (std::exception e) { jack_error("JackALSARawMidiDriver::Open - while creating output " "port array: %s", e.what()); FreeDeviceInfo(&in_info_list, &out_info_list); goto delete_input_ports; } } for (size_t i = 0; i < potential_inputs; i++) { snd_rawmidi_info_t *info = in_info_list.at(i); try { input_ports[num_inputs] = new JackALSARawMidiInputPort(info, i); num_inputs++; } catch (std::exception e) { jack_error("JackALSARawMidiDriver::Open - while creating new " "JackALSARawMidiInputPort: %s", e.what()); } snd_rawmidi_info_free(info); } for (size_t i = 0; i < potential_outputs; i++) { snd_rawmidi_info_t *info = out_info_list.at(i); try { output_ports[num_outputs] = new JackALSARawMidiOutputPort(info, i); num_outputs++; } catch (std::exception e) { jack_error("JackALSARawMidiDriver::Open - while creating new " "JackALSARawMidiOutputPort: %s", e.what()); } snd_rawmidi_info_free(info); } if (! (num_inputs || num_outputs)) { jack_error("JackALSARawMidiDriver::Open - none of the potential " "inputs or outputs were successfully opened."); } else if (JackMidiDriver::Open(capturing, playing, num_inputs, num_outputs, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency)) { jack_error("JackALSARawMidiDriver::Open - JackMidiDriver::Open error"); } else { return 0; } if (output_ports) { for (size_t i = 0; i < num_outputs; i++) { delete output_ports[i]; } delete[] output_ports; output_ports = 0; } delete_input_ports: if (input_ports) { for (size_t i = 0; i < num_inputs; i++) { delete input_ports[i]; } delete[] input_ports; input_ports = 0; } return -1; } int JackALSARawMidiDriver::Read() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fCaptureChannels; i++) { if (! input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size)) { return -1; } } return 0; } int JackALSARawMidiDriver::Start() { jack_info("JackALSARawMidiDriver::Start - Starting 'alsarawmidi' driver."); JackMidiDriver::Start(); poll_fd_count = 1; for (int i = 0; i < fCaptureChannels; i++) { poll_fd_count += input_ports[i]->GetPollDescriptorCount(); } for (int i = 0; i < fPlaybackChannels; i++) { poll_fd_count += output_ports[i]->GetPollDescriptorCount(); } try { poll_fds = new pollfd[poll_fd_count]; } catch (std::exception e) { jack_error("JackALSARawMidiDriver::Start - creating poll descriptor " "structures failed: %s", e.what()); return -1; } if (fPlaybackChannels) { try { output_port_timeouts = new jack_nframes_t[fPlaybackChannels]; } catch (std::exception e) { jack_error("JackALSARawMidiDriver::Start - creating array for " "output port timeout values failed: %s", e.what()); goto free_poll_descriptors; } } struct pollfd *poll_fd_iter; try { CreateNonBlockingPipe(fds); } catch (std::exception e) { jack_error("JackALSARawMidiDriver::Start - while creating wake pipe: " "%s", e.what()); goto free_output_port_timeouts; } poll_fds[0].events = POLLERR | POLLIN | POLLNVAL; poll_fds[0].fd = fds[0]; poll_fd_iter = poll_fds + 1; for (int i = 0; i < fCaptureChannels; i++) { JackALSARawMidiInputPort *input_port = input_ports[i]; input_port->PopulatePollDescriptors(poll_fd_iter); poll_fd_iter += input_port->GetPollDescriptorCount(); } for (int i = 0; i < fPlaybackChannels; i++) { JackALSARawMidiOutputPort *output_port = output_ports[i]; output_port->PopulatePollDescriptors(poll_fd_iter); poll_fd_iter += output_port->GetPollDescriptorCount(); output_port_timeouts[i] = 0; } jack_info("JackALSARawMidiDriver::Start - starting ALSA thread ..."); if (! thread->StartSync()) { jack_info("JackALSARawMidiDriver::Start - started ALSA thread."); return 0; } jack_error("JackALSARawMidiDriver::Start - failed to start MIDI " "processing thread."); DestroyNonBlockingPipe(fds); fds[1] = -1; fds[0] = -1; free_output_port_timeouts: delete[] output_port_timeouts; output_port_timeouts = 0; free_poll_descriptors: delete[] poll_fds; poll_fds = 0; return -1; } int JackALSARawMidiDriver::Stop() { jack_info("JackALSARawMidiDriver::Stop - stopping 'alsarawmidi' driver."); JackMidiDriver::Stop(); if (fds[1] != -1) { close(fds[1]); fds[1] = -1; } int result; const char *verb; switch (thread->GetStatus()) { case JackThread::kIniting: case JackThread::kStarting: result = thread->Kill(); verb = "kill"; break; case JackThread::kRunning: result = thread->Stop(); verb = "stop"; break; default: result = 0; verb = 0; } if (fds[0] != -1) { close(fds[0]); fds[0] = -1; } if (output_port_timeouts) { delete[] output_port_timeouts; output_port_timeouts = 0; } if (poll_fds) { delete[] poll_fds; poll_fds = 0; } if (result) { jack_error("JackALSARawMidiDriver::Stop - could not %s MIDI " "processing thread.", verb); } return result; } int JackALSARawMidiDriver::Write() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fPlaybackChannels; i++) { if (! output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size)) { return -1; } } return 0; } #ifdef __cplusplus extern "C" { #endif // singleton kind of driver static Jack::JackALSARawMidiDriver* driver = NULL; SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() { // X: There could be parameters here regarding setting I/O buffer // sizes. I don't think MIDI drivers can accept parameters right // now without being set as the main driver. return jack_driver_descriptor_construct("alsarawmidi", JackDriverSlave, "Alternative ALSA raw MIDI backend.", NULL); } SERVER_EXPORT Jack::JackDriverClientInterface * driver_initialize(Jack::JackLockedEngine *engine, Jack::JackSynchro *table, const JSList *params) { // singleton kind of driver if (!driver) { driver = new Jack::JackALSARawMidiDriver("system_midi", "alsarawmidi", engine, table); if (driver->Open(1, 1, 0, 0, false, "midi in", "midi out", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } else { jack_info("JackALSARawMidiDriver already allocated, cannot be loaded twice"); return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp0000644000000000000000000000314613214314510022602 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackALSARawMidiReceiveQueue.h" #include "JackError.h" #include "JackMidiUtil.h" using Jack::JackALSARawMidiReceiveQueue; JackALSARawMidiReceiveQueue:: JackALSARawMidiReceiveQueue(snd_rawmidi_t *rawmidi, size_t buffer_size) { buffer = new jack_midi_data_t[buffer_size]; this->buffer_size = buffer_size; this->rawmidi = rawmidi; } JackALSARawMidiReceiveQueue::~JackALSARawMidiReceiveQueue() { delete[] buffer; } jack_midi_event_t * JackALSARawMidiReceiveQueue::DequeueEvent() { ssize_t result = snd_rawmidi_read(rawmidi, buffer, buffer_size); if (result > 0) { event.buffer = buffer; event.size = (size_t) result; event.time = GetCurrentFrame(); return &event; } if (result && (result != -EWOULDBLOCK)) { jack_error("JackALSARawMidiReceiveQueue::DequeueEvent - " "snd_rawmidi_read: %s", snd_strerror(result)); } return 0; } 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiSendQueue.h0000644000000000000000000000262213214314510021554 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackALSARawMidiSendQueue__ #define __JackALSARawMidiSendQueue__ #include #include "JackMidiSendQueue.h" namespace Jack { class JackALSARawMidiSendQueue: public JackMidiSendQueue { private: bool blocked; size_t bytes_available; size_t bytes_per_poll; snd_rawmidi_t *rawmidi; public: JackALSARawMidiSendQueue(snd_rawmidi_t *rawmidi, size_t bytes_per_poll=0); JackMidiWriteQueue::EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); bool IsBlocked(); void ResetPollByteCount(); }; } #endif 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiUtil.h0000644000000000000000000000164113214314510020573 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackALSARawMidiUtil__ #define __JackALSARawMidiUtil__ namespace Jack { void CreateNonBlockingPipe(int *fds); void DestroyNonBlockingPipe(int *fds); void SetNonBlocking(int fd); } #endif 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp0000644000000000000000000000401113214314510022101 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "JackALSARawMidiSendQueue.h" #include "JackMidiUtil.h" #include "JackError.h" using Jack::JackALSARawMidiSendQueue; JackALSARawMidiSendQueue::JackALSARawMidiSendQueue(snd_rawmidi_t *rawmidi, size_t bytes_per_poll) { assert(bytes_per_poll > 0); this->bytes_per_poll = bytes_per_poll; this->rawmidi = rawmidi; blocked = false; bytes_available = bytes_per_poll; } Jack::JackMidiWriteQueue::EnqueueResult JackALSARawMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) { assert(size == 1); if (time > GetCurrentFrame()) { return EVENT_EARLY; } if (! bytes_available) { return BUFFER_FULL; } ssize_t result = snd_rawmidi_write(rawmidi, buffer, 1); switch (result) { case 1: blocked = false; bytes_available--; return OK; case -EWOULDBLOCK: blocked = true; return BUFFER_FULL; } jack_error("JackALSARawMidiSendQueue::EnqueueEvent - snd_rawmidi_write: " "%s", snd_strerror(result)); return EN_ERROR; } bool JackALSARawMidiSendQueue::IsBlocked() { return blocked; } void JackALSARawMidiSendQueue::ResetPollByteCount() { bytes_available = bytes_per_poll; } 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiPort.h0000644000000000000000000000347713214314510020613 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackALSARawMidiPort__ #define __JackALSARawMidiPort__ #include #include #include "JackConstants.h" namespace Jack { class JackALSARawMidiPort { private: char alias[REAL_JACK_PORT_NAME_SIZE+1]; struct pollfd *alsa_poll_fds; int alsa_poll_fd_count; int fds[2]; unsigned short io_mask; char name[REAL_JACK_PORT_NAME_SIZE+1]; struct pollfd *queue_poll_fd; protected: snd_rawmidi_t *rawmidi; int GetIOPollEvent(); int GetQueuePollEvent(); void SetIOEventsEnabled(bool enabled); void SetQueueEventsEnabled(bool enabled); bool TriggerQueueEvent(); public: JackALSARawMidiPort(snd_rawmidi_info_t *info, size_t index, unsigned short io_mask); virtual ~JackALSARawMidiPort(); const char * GetAlias(); const char * GetName(); int GetPollDescriptorCount(); void PopulatePollDescriptors(struct pollfd *poll_fd); }; } #endif 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiUtil.cpp0000644000000000000000000000141413214314510021124 0ustar rootroot#include #include #include #include #include #include "JackALSARawMidiUtil.h" void Jack::CreateNonBlockingPipe(int *fds) { if (pipe(fds) == -1) { throw std::runtime_error(strerror(errno)); } try { SetNonBlocking(fds[0]); SetNonBlocking(fds[1]); } catch (...) { close(fds[1]); close(fds[0]); throw; } } void Jack::DestroyNonBlockingPipe(int *fds) { close(fds[1]); close(fds[0]); } void Jack::SetNonBlocking(int fd) { int flags = fcntl(fd, F_GETFL); if (flags == -1) { throw std::runtime_error(strerror(errno)); } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { throw std::runtime_error(strerror(errno)); } } 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiInputPort.cpp0000644000000000000000000001000013214314510022142 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackALSARawMidiInputPort.h" #include "JackMidiUtil.h" #include "JackError.h" using Jack::JackALSARawMidiInputPort; JackALSARawMidiInputPort::JackALSARawMidiInputPort(snd_rawmidi_info_t *info, size_t index, size_t max_bytes, size_t max_messages): JackALSARawMidiPort(info, index, POLLIN) { alsa_event = 0; jack_event = 0; receive_queue = new JackALSARawMidiReceiveQueue(rawmidi, max_bytes); std::auto_ptr receive_ptr(receive_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); std::auto_ptr thread_ptr(thread_queue); write_queue = new JackMidiBufferWriteQueue(); std::auto_ptr write_ptr(write_queue); raw_queue = new JackMidiRawInputWriteQueue(thread_queue, max_bytes, max_messages); write_ptr.release(); thread_ptr.release(); receive_ptr.release(); } JackALSARawMidiInputPort::~JackALSARawMidiInputPort() { delete raw_queue; delete receive_queue; delete thread_queue; delete write_queue; } bool JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { write_queue->ResetMidiBuffer(port_buffer, frames); bool dequeued = false; if (! jack_event) { goto dequeue_event; } for (;;) { switch (write_queue->EnqueueEvent(jack_event, frames)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackALSARawMidiInputPort::ProcessJack - The write " "queue couldn't enqueue a %d-byte event. Dropping " "event.", jack_event->size); // Fallthrough on purpose. case JackMidiWriteQueue::OK: break; default: goto trigger_queue_event; } dequeue_event: jack_event = thread_queue->DequeueEvent(); if (! jack_event) { break; } dequeued = true; } trigger_queue_event: return dequeued ? TriggerQueueEvent() : true; } bool JackALSARawMidiInputPort::ProcessPollEvents(jack_nframes_t current_frame) { if (GetQueuePollEvent() == -1) { return false; } int io_event = GetIOPollEvent(); switch (io_event) { case -1: return false; case 1: alsa_event = receive_queue->DequeueEvent(); } if (alsa_event) { size_t size = alsa_event->size; size_t space = raw_queue->GetAvailableSpace(); bool enough_room = space >= size; if (enough_room) { assert(raw_queue->EnqueueEvent(current_frame, size, alsa_event->buffer) == JackMidiWriteQueue::OK); alsa_event = 0; } else if (space) { assert(raw_queue->EnqueueEvent(current_frame, space, alsa_event->buffer) == JackMidiWriteQueue::OK); alsa_event->buffer += space; alsa_event->size -= space; } SetIOEventsEnabled(enough_room); } raw_queue->Process(); return true; } 1.9.12~dfsg/linux/alsarawmidi/JackALSARawMidiDriver.h0000644000000000000000000000472413214314510021116 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackALSARawMidiDriver__ #define __JackALSARawMidiDriver__ #include #include #include #include "JackALSARawMidiInputPort.h" #include "JackALSARawMidiOutputPort.h" #include "JackMidiDriver.h" #include "JackThread.h" namespace Jack { class JackALSARawMidiDriver: public JackMidiDriver, public JackRunnableInterface { private: int fds[2]; JackALSARawMidiInputPort **input_ports; JackALSARawMidiOutputPort **output_ports; jack_nframes_t *output_port_timeouts; nfds_t poll_fd_count; struct pollfd *poll_fds; JackThread *thread; void FreeDeviceInfo(std::vector *in_info_list, std::vector *out_info_list); void GetDeviceInfo(snd_ctl_t *control, snd_rawmidi_info_t *info, std::vector *info_list); void HandleALSAError(const char *driver_func, const char *alsa_func, int code); public: JackALSARawMidiDriver(const char *name, const char *alias, JackLockedEngine *engine, JackSynchro *table); ~JackALSARawMidiDriver(); int Attach(); int Close(); bool Execute(); bool Init(); int Open(bool capturing, bool playing, int in_channels, int out_channels, bool monitoring, const char *capture_driver_name, const char *playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); int Read(); int Start(); int Stop(); int Write(); }; } #endif 1.9.12~dfsg/linux/JackLinuxFutex.h0000644000000000000000000000475313214314510015565 0ustar rootroot/* Copyright (C) 2004-2008 Grame Copyright (C) 2016 Filipe Coelho This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackLinuxFutex__ #define __JackLinuxFutex__ #include "JackSynchro.h" #include "JackCompilerDeps.h" #include namespace Jack { /*! \brief Inter process synchronization using Linux futex. Based on the JackPosixSemaphore class. Adapted to work with linux futex to be as light as possible and also work in multiple architectures. Adds a new 'MakePrivate' function that makes the sync happen in the local process only, making it even faster for internal clients. */ class SERVER_EXPORT JackLinuxFutex : public detail::JackSynchro { private: struct FutexData { int futex; // futex, needs to be 1st member bool internal; // current internal state bool wasInternal; // initial internal state, only changes in allocate bool needsChange; // change state on next wait call int externalCount; // how many external clients have connected }; int fSharedMem; FutexData* fFutex; bool fPrivate; bool fPromiscuous; int fPromiscuousGid; protected: void BuildName(const char* name, const char* server_name, char* res, int size); public: JackLinuxFutex(); bool Signal(); bool SignalAll(); bool Wait(); bool TimedWait(long usec); bool Allocate(const char* name, const char* server_name, int value, bool internal = false); bool Connect(const char* name, const char* server_name); bool ConnectInput(const char* name, const char* server_name); bool ConnectOutput(const char* name, const char* server_name); bool Disconnect(); void Destroy(); void MakePrivate(bool priv); }; } // end of namespace #endif 1.9.12~dfsg/linux/JackAtomic_os.h0000644000000000000000000000450313214314510015360 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAtomic_linux__ #define __JackAtomic_linux__ #include "JackTypes.h" #ifdef __PPC__ static inline int CAS(register UInt32 value, register UInt32 newvalue, register volatile void* addr) { register int result; register UInt32 tmp; asm volatile ( "# CAS \n" " lwarx %4, 0, %1 \n" // creates a reservation on addr " cmpw %4, %2 \n" // test value at addr " bne- 1f \n" " sync \n" // synchronize instructions " stwcx. %3, 0, %1 \n" // if the reservation is not altered // stores the new value at addr " bne- 1f \n" " li %0, 1 \n" " b 2f \n" "1: \n" " li %0, 0 \n" "2: \n" : "=r" (result) : "r" (addr), "r" (value), "r" (newvalue), "r" (tmp) ); return result; } #endif #if defined(__i386__) || defined(__x86_64__) #define LOCK "lock ; " static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) { register char ret; __asm__ __volatile__ ( "# CAS \n\t" LOCK "cmpxchg %2, (%1) \n\t" "sete %0 \n\t" : "=a" (ret) : "c" (addr), "d" (newvalue), "a" (value) ); return ret; } #endif #if !defined(__i386__) && !defined(__x86_64__) && !defined(__PPC__) static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) { return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue); } #endif #endif 1.9.12~dfsg/linux/JackPlatformPlug_os.h0000644000000000000000000000521313214314510016557 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPlatformPlug_linux__ #define __JackPlatformPlug_linux__ #define jack_server_dir "/dev/shm" #define jack_client_dir "/dev/shm" #define JACK_DEFAULT_DRIVER "alsa" namespace Jack { struct JackRequest; struct JackResult; class JackPosixMutex; class JackPosixThread; class JackFifo; class JackSocketServerChannel; class JackSocketClientChannel; class JackSocketServerNotifyChannel; class JackSocketNotifyChannel; class JackClientSocket; class JackNetUnixSocket; } /* __JackPlatformMutex__ */ #include "JackPosixMutex.h" namespace Jack {typedef JackPosixMutex JackMutex; } /* __JackPlatformThread__ */ #include "JackPosixThread.h" namespace Jack { typedef JackPosixThread JackThread; } /* __JackPlatformSynchro__ client activation */ /* #include "JackFifo.h" namespace Jack { typedef JackFifo JackSynchro; } */ #include "JackLinuxFutex.h" namespace Jack { typedef JackLinuxFutex JackSynchro; } /* __JackPlatformChannelTransaction__ */ /* #include "JackSocket.h" namespace Jack { typedef JackClientSocket JackChannelTransaction; } */ /* __JackPlatformProcessSync__ */ #include "JackPosixProcessSync.h" namespace Jack { typedef JackPosixProcessSync JackProcessSync; } /* __JackPlatformServerChannel__ */ #include "JackSocketServerChannel.h" namespace Jack { typedef JackSocketServerChannel JackServerChannel; } /* __JackPlatformClientChannel__ */ #include "JackSocketClientChannel.h" namespace Jack { typedef JackSocketClientChannel JackClientChannel; } /* __JackPlatformServerNotifyChannel__ */ #include "JackSocketServerNotifyChannel.h" namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; } /* __JackPlatformNotifyChannel__ */ #include "JackSocketNotifyChannel.h" namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; } /* __JackPlatformNetSocket__ */ #include "JackNetUnixSocket.h" namespace Jack { typedef JackNetUnixSocket JackNetSocket; } #endif 1.9.12~dfsg/linux/alsa/0000755000000000000000000000000013214314510013417 5ustar rootroot1.9.12~dfsg/linux/alsa/generic.h0000644000000000000000000000177713214314510015220 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: generic.h,v 1.3 2005/11/23 11:24:29 letz Exp $ */ #ifndef __jack_generic_h__ #define __jack_generic_h__ #ifdef __cplusplus extern "C" { #endif jack_hardware_t * jack_alsa_generic_hw_new (alsa_driver_t *driver); #ifdef __cplusplus } #endif #endif /* __jack_generic_h__*/ 1.9.12~dfsg/linux/alsa/generic_hw.c0000644000000000000000000000272713214314510015705 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: generic_hw.c,v 1.2 2005/08/29 10:36:28 letz Exp $ */ #include "hardware.h" #include "alsa_driver.h" static int generic_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) { return -1; } static int generic_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) { return -1; } static void generic_release (jack_hardware_t *hw) { return; } jack_hardware_t * jack_alsa_generic_hw_new (alsa_driver_t *driver) { jack_hardware_t *hw; hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); hw->capabilities = 0; hw->input_monitor_mask = 0; hw->set_input_monitor_mask = generic_set_input_monitor_mask; hw->change_sample_clock = generic_change_sample_clock; hw->release = generic_release; return hw; } 1.9.12~dfsg/linux/alsa/hdsp.c0000644000000000000000000001617113214314510014527 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2002 Dave LaRose This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: hdsp.c,v 1.3 2005/09/29 14:51:59 letz Exp $ */ #include "hardware.h" #include "alsa_driver.h" #include "hdsp.h" #include "JackError.h" /* Constants to make working with the hdsp matrix mixer easier */ static const int HDSP_MINUS_INFINITY_GAIN = 0; static const int HDSP_UNITY_GAIN = 32768; static const int HDSP_MAX_GAIN = 65535; /* * Use these two arrays to choose the value of the input_channel * argument to hsdp_set_mixer_gain(). hdsp_physical_input_index[n] * selects the nth optical/analog input. audio_stream_index[n] * selects the nth channel being received from the host via pci/pccard. */ static const int hdsp_num_input_channels = 52; static const int hdsp_physical_input_index[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}; static const int hdsp_audio_stream_index[] = { 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; /* * Use this array to choose the value of the output_channel * argument to hsdp_set_mixer_gain(). hdsp_physical_output_index[26] * and hdsp_physical_output_index[27] refer to the two "line out" * channels (1/4" phone jack on the front of digiface/multiface). */ static const int hdsp_num_output_channels = 28; static const int hdsp_physical_output_index[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}; /* Function for checking argument values */ static int clamp_int(int value, int lower_bound, int upper_bound) { if(value < lower_bound) { return lower_bound; } if(value > upper_bound) { return upper_bound; } return value; } /* Note(XXX): Maybe should share this code with hammerfall.c? */ static void set_control_id (snd_ctl_elem_id_t *ctl, const char *name) { snd_ctl_elem_id_set_name (ctl, name); snd_ctl_elem_id_set_numid (ctl, 0); snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_HWDEP); snd_ctl_elem_id_set_device (ctl, 0); snd_ctl_elem_id_set_subdevice (ctl, 0); snd_ctl_elem_id_set_index (ctl, 0); } /* The hdsp matrix mixer lets you connect pretty much any input to */ /* any output with gain from -inf to about +2dB. Pretty slick. */ /* This routine makes a convenient way to set the gain from */ /* input_channel to output_channel (see hdsp_physical_input_index */ /* etc. above. */ /* gain is an int from 0 to 65535, with 0 being -inf gain, and */ /* 65535 being about +2dB. */ static int hdsp_set_mixer_gain(jack_hardware_t *hw, int input_channel, int output_channel, int gain) { hdsp_t *h = (hdsp_t *) hw->private_hw; snd_ctl_elem_value_t *ctl; snd_ctl_elem_id_t *ctl_id; int err; /* Check args */ input_channel = clamp_int(input_channel, 0, hdsp_num_input_channels); output_channel = clamp_int(output_channel, 0, hdsp_num_output_channels); gain = clamp_int(gain, HDSP_MINUS_INFINITY_GAIN, HDSP_MAX_GAIN); /* Allocate control element and select "Mixer" control */ snd_ctl_elem_value_alloca (&ctl); snd_ctl_elem_id_alloca (&ctl_id); set_control_id (ctl_id, "Mixer"); snd_ctl_elem_value_set_id (ctl, ctl_id); /* Apparently non-standard and unstable interface for the */ /* mixer control. */ snd_ctl_elem_value_set_integer (ctl, 0, input_channel); snd_ctl_elem_value_set_integer (ctl, 1, output_channel); snd_ctl_elem_value_set_integer (ctl, 2, gain); /* Commit the mixer value and check for errors */ if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) != 0) { jack_error ("ALSA/HDSP: cannot set mixer gain (%s)", snd_strerror (err)); return -1; } /* Note (XXX): Perhaps we should maintain a cache of the current */ /* mixer values, since it's not clear how to query them from the */ /* hdsp hardware. We'll leave this out until a little later. */ return 0; } static int hdsp_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) { int i; /* For each input channel */ for (i = 0; i < 26; i++) { /* Monitoring requested for this channel? */ if(mask & (1<input_monitor_mask = mask; return 0; } static int hdsp_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) { // Empty for now, until Dave understands more about clock sync so // he can test. return -1; } static double hdsp_get_hardware_peak (jack_port_t *port, jack_nframes_t frame) { return 0; } static double hdsp_get_hardware_power (jack_port_t *port, jack_nframes_t frame) { return 0; } static void hdsp_release (jack_hardware_t *hw) { hdsp_t *h = (hdsp_t *) hw->private_hw; if (h != 0) { free (h); } } /* Mostly copied directly from hammerfall.c */ jack_hardware_t * jack_alsa_hdsp_hw_new (alsa_driver_t *driver) { jack_hardware_t *hw; hdsp_t *h; hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); /* Not using clock lock-sync-whatever in home hardware setup */ /* yet. Will write this code when can test it. */ /* hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting; */ hw->capabilities = Cap_HardwareMonitoring | Cap_HardwareMetering; hw->input_monitor_mask = 0; hw->private_hw = 0; hw->set_input_monitor_mask = hdsp_set_input_monitor_mask; hw->change_sample_clock = hdsp_change_sample_clock; hw->release = hdsp_release; hw->get_hardware_peak = hdsp_get_hardware_peak; hw->get_hardware_power = hdsp_get_hardware_power; h = (hdsp_t *) malloc (sizeof (hdsp_t)); h->driver = driver; hw->private_hw = h; return hw; } 1.9.12~dfsg/linux/alsa/midi_unpack.h0000644000000000000000000001053313214314510016055 0ustar rootroot/* * Copyright (c) 2006,2007 Dmitry S. Baikov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __jack_midi_unpack_h__ #define __jack_midi_unpack_h__ enum { MIDI_UNPACK_MAX_MSG = 1024 }; typedef struct { int pos, need, size; unsigned char data[MIDI_UNPACK_MAX_MSG]; } midi_unpack_t; static inline void midi_unpack_init(midi_unpack_t *u) { u->pos = 0; u->size = sizeof(u->data); u->need = u->size; } static inline void midi_unpack_reset(midi_unpack_t *u) { u->pos = 0; u->need = u->size; } static const unsigned char midi_voice_len[] = { 3, /*0x80 Note Off*/ 3, /*0x90 Note On*/ 3, /*0xA0 Aftertouch*/ 3, /*0xB0 Control Change*/ 2, /*0xC0 Program Change*/ 2, /*0xD0 Channel Pressure*/ 3, /*0xE0 Pitch Wheel*/ 1 /*0xF0 System*/ }; static const unsigned char midi_system_len[] = { 0, /*0xF0 System Exclusive Start*/ 2, /*0xF1 MTC Quarter Frame*/ 3, /*0xF2 Song Postion*/ 2, /*0xF3 Song Select*/ 0, /*0xF4 undefined*/ 0, /*0xF5 undefined*/ 1, /*0xF6 Tune Request*/ 1 /*0xF7 System Exlusive End*/ }; static int midi_unpack_buf(midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time) { int i; for (i = 0; i < len; ++i) { const unsigned char byte = data[i]; if (byte >= 0xF8) // system realtime { jack_midi_event_write(jack_port_buf, time, &data[i], 1); //printf("midi_unpack: written system relatime event\n"); //midi_input_write(in, &data[i], 1); } else if (byte < 0x80) // data { assert (buf->pos < buf->size); buf->data[buf->pos++] = byte; } else if (byte < 0xF0) // voice { assert (byte >= 0x80 && byte < 0xF0); //buf->need = ((byte|0x0F) == 0xCF || (byte|0x0F)==0xDF) ? 2 : 3; buf->need = midi_voice_len[(byte-0x80)>>4]; buf->data[0] = byte; buf->pos = 1; } else if (byte == 0xF7) // sysex end { assert (buf->pos < buf->size); buf->data[buf->pos++] = byte; buf->need = buf->pos; } else { assert (byte >= 0xF0 && byte < 0xF8); buf->pos = 1; buf->data[0] = byte; buf->need = midi_system_len[byte - 0xF0]; if (!buf->need) buf->need = buf->size; } if (buf->pos == buf->need) { // TODO: deal with big sysex'es (they are silently dropped for now) if (buf->data[0] >= 0x80 || (buf->data[0] == 0xF0 && buf->data[buf->pos-1] == 0xF7)) { /* convert Note On with velocity 0 to Note Off */ if ((buf->data[0] & 0xF0) == 0x90 && buf->data[2] == 0) { // we use temp array here to keep running status sync jack_midi_data_t temp[3] = { 0x80, 0, 0x40 }; temp[0] |= buf->data[0] & 0x0F; temp[1] = buf->data[1]; jack_midi_event_write(jack_port_buf, time, temp, 3); } else jack_midi_event_write(jack_port_buf, time, &buf->data[0], buf->pos); //printf("midi_unpack: written %d-byte event\n", buf->pos); //midi_input_write(in, &buf->data[0], buf->pos); } /* keep running status */ if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0) buf->pos = 1; else { buf->pos = 0; buf->need = buf->size; } } } assert (i == len); return i; } #endif /* __jack_midi_unpack_h__ */ 1.9.12~dfsg/linux/alsa/alsa_driver.c0000644000000000000000000016604713214314510016074 0ustar rootroot/* -*- mode: c; c-file-style: "linux"; -*- */ /* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define __STDC_FORMAT_MACROS // For inttypes.h to work in C++ #define _GNU_SOURCE /* for strcasestr() from string.h */ #include #include #include #include #include #include #include #include #include #include #include #include "alsa_driver.h" #include "hammerfall.h" #include "hdsp.h" #include "ice1712.h" #include "usx2y.h" #include "generic.h" #include "memops.h" #include "JackError.h" #include "alsa_midi_impl.h" extern void store_work_time (int); extern void store_wait_time (int); extern void show_wait_times (); extern void show_work_times (); #undef DEBUG_WAKEUP char* strcasestr(const char* haystack, const char* needle); /* Delay (in process calls) before jackd will report an xrun */ #define XRUN_REPORT_DELAY 0 void jack_driver_init (jack_driver_t *driver) { memset (driver, 0, sizeof (*driver)); driver->attach = 0; driver->detach = 0; driver->write = 0; driver->read = 0; driver->null_cycle = 0; driver->bufsize = 0; driver->start = 0; driver->stop = 0; } void jack_driver_nt_init (jack_driver_nt_t * driver) { memset (driver, 0, sizeof (*driver)); jack_driver_init ((jack_driver_t *) driver); driver->attach = 0; driver->detach = 0; driver->bufsize = 0; driver->stop = 0; driver->start = 0; driver->nt_bufsize = 0; driver->nt_start = 0; driver->nt_stop = 0; driver->nt_attach = 0; driver->nt_detach = 0; driver->nt_run_cycle = 0; } static void alsa_driver_release_channel_dependent_memory (alsa_driver_t *driver) { bitset_destroy (&driver->channels_done); bitset_destroy (&driver->channels_not_done); if (driver->playback_addr) { free (driver->playback_addr); driver->playback_addr = 0; } if (driver->capture_addr) { free (driver->capture_addr); driver->capture_addr = 0; } if (driver->playback_interleave_skip) { free (driver->playback_interleave_skip); driver->playback_interleave_skip = NULL; } if (driver->capture_interleave_skip) { free (driver->capture_interleave_skip); driver->capture_interleave_skip = NULL; } if (driver->silent) { free (driver->silent); driver->silent = 0; } if (driver->dither_state) { free (driver->dither_state); driver->dither_state = 0; } } static int alsa_driver_check_capabilities (alsa_driver_t *driver) { return 0; } char* get_control_device_name(const char * device_name); static int alsa_driver_check_card_type (alsa_driver_t *driver) { int err; snd_ctl_card_info_t *card_info; char * ctl_name; snd_ctl_card_info_alloca (&card_info); ctl_name = get_control_device_name(driver->alsa_name_playback); // XXX: I don't know the "right" way to do this. Which to use // driver->alsa_name_playback or driver->alsa_name_capture. if ((err = snd_ctl_open (&driver->ctl_handle, ctl_name, 0)) < 0) { jack_error ("control open \"%s\" (%s)", ctl_name, snd_strerror(err)); } else if ((err = snd_ctl_card_info(driver->ctl_handle, card_info)) < 0) { jack_error ("control hardware info \"%s\" (%s)", driver->alsa_name_playback, snd_strerror (err)); snd_ctl_close (driver->ctl_handle); } driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info)); free(ctl_name); return alsa_driver_check_capabilities (driver); } static int alsa_driver_hammerfall_hardware (alsa_driver_t *driver) { driver->hw = jack_alsa_hammerfall_hw_new (driver); return 0; } static int alsa_driver_hdsp_hardware (alsa_driver_t *driver) { driver->hw = jack_alsa_hdsp_hw_new (driver); return 0; } static int alsa_driver_ice1712_hardware (alsa_driver_t *driver) { driver->hw = jack_alsa_ice1712_hw_new (driver); return 0; } // JACK2 /* static int alsa_driver_usx2y_hardware (alsa_driver_t *driver) { driver->hw = jack_alsa_usx2y_hw_new (driver); return 0; } */ static int alsa_driver_generic_hardware (alsa_driver_t *driver) { driver->hw = jack_alsa_generic_hw_new (driver); return 0; } static int alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitoring, int hw_metering) { int err; if (!strcmp(driver->alsa_driver, "RME9652")) { if ((err = alsa_driver_hammerfall_hardware (driver)) != 0) { return err; } } else if (!strcmp(driver->alsa_driver, "H-DSP")) { if ((err = alsa_driver_hdsp_hardware (driver)) !=0) { return err; } } else if (!strcmp(driver->alsa_driver, "ICE1712")) { if ((err = alsa_driver_ice1712_hardware (driver)) !=0) { return err; } } // JACK2 /* else if (!strcmp(driver->alsa_driver, "USB US-X2Y")) { if ((err = alsa_driver_usx2y_hardware (driver)) !=0) { return err; } } */ else { if ((err = alsa_driver_generic_hardware (driver)) != 0) { return err; } } if (driver->hw->capabilities & Cap_HardwareMonitoring) { driver->has_hw_monitoring = TRUE; /* XXX need to ensure that this is really FALSE or * TRUE or whatever*/ driver->hw_monitoring = hw_monitoring; } else { driver->has_hw_monitoring = FALSE; driver->hw_monitoring = FALSE; } if (driver->hw->capabilities & Cap_ClockLockReporting) { driver->has_clock_sync_reporting = TRUE; } else { driver->has_clock_sync_reporting = FALSE; } if (driver->hw->capabilities & Cap_HardwareMetering) { driver->has_hw_metering = TRUE; driver->hw_metering = hw_metering; } else { driver->has_hw_metering = FALSE; driver->hw_metering = FALSE; } return 0; } static void alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) { if (driver->playback_handle) { if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { driver->write_via_copy = sample_move_dS_floatLE; } else { switch (driver->playback_sample_bytes) { case 2: switch (driver->dither) { case Rectangular: jack_info("Rectangular dithering at 16 bits"); driver->write_via_copy = driver->quirk_bswap? sample_move_dither_rect_d16_sSs: sample_move_dither_rect_d16_sS; break; case Triangular: jack_info("Triangular dithering at 16 bits"); driver->write_via_copy = driver->quirk_bswap? sample_move_dither_tri_d16_sSs: sample_move_dither_tri_d16_sS; break; case Shaped: jack_info("Noise-shaped dithering at 16 bits"); driver->write_via_copy = driver->quirk_bswap? sample_move_dither_shaped_d16_sSs: sample_move_dither_shaped_d16_sS; break; default: driver->write_via_copy = driver->quirk_bswap? sample_move_d16_sSs : sample_move_d16_sS; break; } break; case 3: /* NO DITHER */ driver->write_via_copy = driver->quirk_bswap? sample_move_d24_sSs: sample_move_d24_sS; break; case 4: /* NO DITHER */ driver->write_via_copy = driver->quirk_bswap? sample_move_d32u24_sSs: sample_move_d32u24_sS; break; default: jack_error ("impossible sample width (%d) discovered!", driver->playback_sample_bytes); exit (1); } } } if (driver->capture_handle) { if (SND_PCM_FORMAT_FLOAT_LE == driver->capture_sample_format) { driver->read_via_copy = sample_move_floatLE_sSs; } else { switch (driver->capture_sample_bytes) { case 2: driver->read_via_copy = driver->quirk_bswap? sample_move_dS_s16s: sample_move_dS_s16; break; case 3: driver->read_via_copy = driver->quirk_bswap? sample_move_dS_s24s: sample_move_dS_s24; break; case 4: driver->read_via_copy = driver->quirk_bswap? sample_move_dS_s32u24s: sample_move_dS_s32u24; break; } } } } static int alsa_driver_configure_stream (alsa_driver_t *driver, char *device_name, const char *stream_name, snd_pcm_t *handle, snd_pcm_hw_params_t *hw_params, snd_pcm_sw_params_t *sw_params, unsigned int *nperiodsp, channel_t *nchns, unsigned long sample_width) { int err, format; unsigned int frame_rate; snd_pcm_uframes_t stop_th; static struct { char Name[40]; snd_pcm_format_t format; int swapped; } formats[] = { {"32bit float little-endian", SND_PCM_FORMAT_FLOAT_LE, IS_LE}, {"32bit integer little-endian", SND_PCM_FORMAT_S32_LE, IS_LE}, {"32bit integer big-endian", SND_PCM_FORMAT_S32_BE, IS_BE}, {"24bit little-endian in 3bytes format", SND_PCM_FORMAT_S24_3LE, IS_LE}, {"24bit big-endian in 3bytes format", SND_PCM_FORMAT_S24_3BE, IS_BE}, {"24bit little-endian", SND_PCM_FORMAT_S24_LE, IS_LE}, {"24bit big-endian", SND_PCM_FORMAT_S24_BE, IS_BE}, {"16bit little-endian", SND_PCM_FORMAT_S16_LE, IS_LE}, {"16bit big-endian", SND_PCM_FORMAT_S16_BE, IS_BE}, }; #define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) #define FIRST_16BIT_FORMAT 5 if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) { jack_error ("ALSA: no playback configurations available (%s)", snd_strerror (err)); return -1; } if ((err = snd_pcm_hw_params_set_periods_integer (handle, hw_params)) < 0) { jack_error ("ALSA: cannot restrict period size to integral" " value."); return -1; } if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) < 0) { if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) { if ((err = snd_pcm_hw_params_set_access ( handle, hw_params, SND_PCM_ACCESS_MMAP_COMPLEX)) < 0) { jack_error ("ALSA: mmap-based access is not possible" " for the %s " "stream of this audio interface", stream_name); return -1; } } } format = (sample_width == 4) ? 0 : NUMFORMATS - 1; while (1) { if ((err = snd_pcm_hw_params_set_format ( handle, hw_params, formats[format].format)) < 0) { if ((sample_width == 4 ? format++ >= NUMFORMATS - 1 : format-- <= 0)) { jack_error ("Sorry. The audio interface \"%s\"" " doesn't support any of the" " hardware sample formats that" " JACK's alsa-driver can use.", device_name); return -1; } } else { if (formats[format].swapped) { driver->quirk_bswap = 1; } else { driver->quirk_bswap = 0; } jack_info ("ALSA: final selected sample format for %s: %s", stream_name, formats[format].Name); break; } } frame_rate = driver->frame_rate ; err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &frame_rate, NULL) ; driver->frame_rate = frame_rate ; if (err < 0) { jack_error ("ALSA: cannot set sample/frame rate to %" PRIu32 " for %s", driver->frame_rate, stream_name); return -1; } if (!*nchns) { /*if not user-specified, try to find the maximum * number of channels */ unsigned int channels_max ; err = snd_pcm_hw_params_get_channels_max (hw_params, &channels_max); *nchns = channels_max ; if (*nchns > 1024) { /* the hapless user is an unwitting victim of the "default" ALSA PCM device, which can support up to 16 million channels. since they can't be bothered to set up a proper default device, limit the number of channels for them to a sane default. */ jack_error ( "You appear to be using the ALSA software \"plug\" layer, probably\n" "a result of using the \"default\" ALSA device. This is less\n" "efficient than it could be. Consider using a hardware device\n" "instead rather than using the plug layer. Usually the name of the\n" "hardware device that corresponds to the first sound card is hw:0\n" ); *nchns = 2; } } if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, *nchns)) < 0) { jack_error ("ALSA: cannot set channel count to %u for %s", *nchns, stream_name); return -1; } if ((err = snd_pcm_hw_params_set_period_size (handle, hw_params, driver->frames_per_cycle, 0)) < 0) { jack_error ("ALSA: cannot set period size to %" PRIu32 " frames for %s", driver->frames_per_cycle, stream_name); return -1; } *nperiodsp = driver->user_nperiods; snd_pcm_hw_params_set_periods_min (handle, hw_params, nperiodsp, NULL); if (*nperiodsp < driver->user_nperiods) *nperiodsp = driver->user_nperiods; if (snd_pcm_hw_params_set_periods_near (handle, hw_params, nperiodsp, NULL) < 0) { jack_error ("ALSA: cannot set number of periods to %u for %s", *nperiodsp, stream_name); return -1; } if (*nperiodsp < driver->user_nperiods) { jack_error ("ALSA: got smaller periods %u than %u for %s", *nperiodsp, (unsigned int) driver->user_nperiods, stream_name); return -1; } jack_info ("ALSA: use %d periods for %s", *nperiodsp, stream_name); #if 0 if (!jack_power_of_two(driver->frames_per_cycle)) { jack_error("JACK: frames must be a power of two " "(64, 512, 1024, ...)\n"); return -1; } #endif if ((err = snd_pcm_hw_params_set_buffer_size (handle, hw_params, *nperiodsp * driver->frames_per_cycle)) < 0) { jack_error ("ALSA: cannot set buffer length to %" PRIu32 " for %s", *nperiodsp * driver->frames_per_cycle, stream_name); return -1; } if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) { jack_error ("ALSA: cannot set hardware parameters for %s", stream_name); return -1; } snd_pcm_sw_params_current (handle, sw_params); if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, 0U)) < 0) { jack_error ("ALSA: cannot set start mode for %s", stream_name); return -1; } stop_th = *nperiodsp * driver->frames_per_cycle; if (driver->soft_mode) { stop_th = (snd_pcm_uframes_t)-1; } if ((err = snd_pcm_sw_params_set_stop_threshold ( handle, sw_params, stop_th)) < 0) { jack_error ("ALSA: cannot set stop mode for %s", stream_name); return -1; } if ((err = snd_pcm_sw_params_set_silence_threshold ( handle, sw_params, 0)) < 0) { jack_error ("ALSA: cannot set silence threshold for %s", stream_name); return -1; } #if 0 jack_info ("set silence size to %lu * %lu = %lu", driver->frames_per_cycle, *nperiodsp, driver->frames_per_cycle * *nperiodsp); if ((err = snd_pcm_sw_params_set_silence_size ( handle, sw_params, driver->frames_per_cycle * *nperiodsp)) < 0) { jack_error ("ALSA: cannot set silence size for %s", stream_name); return -1; } #endif if (handle == driver->playback_handle) err = snd_pcm_sw_params_set_avail_min ( handle, sw_params, driver->frames_per_cycle * (*nperiodsp - driver->user_nperiods + 1)); else err = snd_pcm_sw_params_set_avail_min ( handle, sw_params, driver->frames_per_cycle); if (err < 0) { jack_error ("ALSA: cannot set avail min for %s", stream_name); return -1; } if ((err = snd_pcm_sw_params (handle, sw_params)) < 0) { jack_error ("ALSA: cannot set software parameters for %s\n", stream_name); return -1; } return 0; } static int alsa_driver_set_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cycle, jack_nframes_t user_nperiods, jack_nframes_t rate) { int dir; snd_pcm_uframes_t p_period_size = 0; snd_pcm_uframes_t c_period_size = 0; channel_t chn; unsigned int pr = 0; unsigned int cr = 0; int err; driver->frame_rate = rate; driver->frames_per_cycle = frames_per_cycle; driver->user_nperiods = user_nperiods; jack_info ("configuring for %" PRIu32 "Hz, period = %" PRIu32 " frames (%.1f ms), buffer = %" PRIu32 " periods", rate, frames_per_cycle, (((float)frames_per_cycle / (float) rate) * 1000.0f), user_nperiods); if (driver->capture_handle) { if (alsa_driver_configure_stream ( driver, driver->alsa_name_capture, "capture", driver->capture_handle, driver->capture_hw_params, driver->capture_sw_params, &driver->capture_nperiods, &driver->capture_nchannels, driver->capture_sample_bytes)) { jack_error ("ALSA: cannot configure capture channel"); return -1; } } if (driver->playback_handle) { if (alsa_driver_configure_stream ( driver, driver->alsa_name_playback, "playback", driver->playback_handle, driver->playback_hw_params, driver->playback_sw_params, &driver->playback_nperiods, &driver->playback_nchannels, driver->playback_sample_bytes)) { jack_error ("ALSA: cannot configure playback channel"); return -1; } } /* check the rate, since thats rather important */ if (driver->playback_handle) { snd_pcm_hw_params_get_rate (driver->playback_hw_params, &pr, &dir); } if (driver->capture_handle) { snd_pcm_hw_params_get_rate (driver->capture_hw_params, &cr, &dir); } if (driver->capture_handle && driver->playback_handle) { if (cr != pr) { jack_error ("playback and capture sample rates do " "not match (%d vs. %d)", pr, cr); } /* only change if *both* capture and playback rates * don't match requested certain hardware actually * still works properly in full-duplex with slightly * different rate values between adc and dac */ if (cr != driver->frame_rate && pr != driver->frame_rate) { jack_error ("sample rate in use (%d Hz) does not " "match requested rate (%d Hz)", cr, driver->frame_rate); driver->frame_rate = cr; } } else if (driver->capture_handle && cr != driver->frame_rate) { jack_error ("capture sample rate in use (%d Hz) does not " "match requested rate (%d Hz)", cr, driver->frame_rate); driver->frame_rate = cr; } else if (driver->playback_handle && pr != driver->frame_rate) { jack_error ("playback sample rate in use (%d Hz) does not " "match requested rate (%d Hz)", pr, driver->frame_rate); driver->frame_rate = pr; } /* check the fragment size, since thats non-negotiable */ if (driver->playback_handle) { snd_pcm_access_t access; err = snd_pcm_hw_params_get_period_size ( driver->playback_hw_params, &p_period_size, &dir); err = snd_pcm_hw_params_get_format ( driver->playback_hw_params, &(driver->playback_sample_format)); err = snd_pcm_hw_params_get_access (driver->playback_hw_params, &access); driver->playback_interleaved = (access == SND_PCM_ACCESS_MMAP_INTERLEAVED) || (access == SND_PCM_ACCESS_MMAP_COMPLEX); if (p_period_size != driver->frames_per_cycle) { jack_error ("alsa_pcm: requested an interrupt every %" PRIu32 " frames but got %u frames for playback", driver->frames_per_cycle, p_period_size); return -1; } } if (driver->capture_handle) { snd_pcm_access_t access; err = snd_pcm_hw_params_get_period_size ( driver->capture_hw_params, &c_period_size, &dir); err = snd_pcm_hw_params_get_format ( driver->capture_hw_params, &(driver->capture_sample_format)); err = snd_pcm_hw_params_get_access (driver->capture_hw_params, &access); driver->capture_interleaved = (access == SND_PCM_ACCESS_MMAP_INTERLEAVED) || (access == SND_PCM_ACCESS_MMAP_COMPLEX); if (c_period_size != driver->frames_per_cycle) { jack_error ("alsa_pcm: requested an interrupt every %" PRIu32 " frames but got %uc frames for capture", driver->frames_per_cycle, p_period_size); return -1; } } driver->playback_sample_bytes = snd_pcm_format_physical_width (driver->playback_sample_format) / 8; driver->capture_sample_bytes = snd_pcm_format_physical_width (driver->capture_sample_format) / 8; if (driver->playback_handle) { switch (driver->playback_sample_format) { case SND_PCM_FORMAT_FLOAT_LE: case SND_PCM_FORMAT_S32_LE: case SND_PCM_FORMAT_S24_3LE: case SND_PCM_FORMAT_S24_3BE: case SND_PCM_FORMAT_S24_LE: case SND_PCM_FORMAT_S24_BE: case SND_PCM_FORMAT_S16_LE: case SND_PCM_FORMAT_S32_BE: case SND_PCM_FORMAT_S16_BE: break; default: jack_error ("programming error: unhandled format " "type for playback"); exit (1); } } if (driver->capture_handle) { switch (driver->capture_sample_format) { case SND_PCM_FORMAT_FLOAT_LE: case SND_PCM_FORMAT_S32_LE: case SND_PCM_FORMAT_S24_3LE: case SND_PCM_FORMAT_S24_3BE: case SND_PCM_FORMAT_S24_LE: case SND_PCM_FORMAT_S24_BE: case SND_PCM_FORMAT_S16_LE: case SND_PCM_FORMAT_S32_BE: case SND_PCM_FORMAT_S16_BE: break; default: jack_error ("programming error: unhandled format " "type for capture"); exit (1); } } if (driver->playback_interleaved) { const snd_pcm_channel_area_t *my_areas; snd_pcm_uframes_t offset, frames; if (snd_pcm_mmap_begin(driver->playback_handle, &my_areas, &offset, &frames) < 0) { jack_error ("ALSA: %s: mmap areas info error", driver->alsa_name_playback); return -1; } driver->interleave_unit = snd_pcm_format_physical_width ( driver->playback_sample_format) / 8; } else { driver->interleave_unit = 0; /* NOT USED */ } if (driver->capture_interleaved) { const snd_pcm_channel_area_t *my_areas; snd_pcm_uframes_t offset, frames; if (snd_pcm_mmap_begin(driver->capture_handle, &my_areas, &offset, &frames) < 0) { jack_error ("ALSA: %s: mmap areas info error", driver->alsa_name_capture); return -1; } } if (driver->playback_nchannels > driver->capture_nchannels) { driver->max_nchannels = driver->playback_nchannels; driver->user_nchannels = driver->capture_nchannels; } else { driver->max_nchannels = driver->capture_nchannels; driver->user_nchannels = driver->playback_nchannels; } alsa_driver_setup_io_function_pointers (driver); /* Allocate and initialize structures that rely on the channels counts. Set up the bit pattern that is used to record which channels require action on every cycle. any bits that are not set after the engine's process() call indicate channels that potentially need to be silenced. */ bitset_create (&driver->channels_done, driver->max_nchannels); bitset_create (&driver->channels_not_done, driver->max_nchannels); if (driver->playback_handle) { driver->playback_addr = (char **) malloc (sizeof (char *) * driver->playback_nchannels); memset (driver->playback_addr, 0, sizeof (char *) * driver->playback_nchannels); driver->playback_interleave_skip = (unsigned long *) malloc (sizeof (unsigned long *) * driver->playback_nchannels); memset (driver->playback_interleave_skip, 0, sizeof (unsigned long *) * driver->playback_nchannels); driver->silent = (unsigned long *) malloc (sizeof (unsigned long) * driver->playback_nchannels); for (chn = 0; chn < driver->playback_nchannels; chn++) { driver->silent[chn] = 0; } for (chn = 0; chn < driver->playback_nchannels; chn++) { bitset_add (driver->channels_done, chn); } driver->dither_state = (dither_state_t *) calloc ( driver->playback_nchannels, sizeof (dither_state_t)); } if (driver->capture_handle) { driver->capture_addr = (char **) malloc (sizeof (char *) * driver->capture_nchannels); memset (driver->capture_addr, 0, sizeof (char *) * driver->capture_nchannels); driver->capture_interleave_skip = (unsigned long *) malloc (sizeof (unsigned long *) * driver->capture_nchannels); memset (driver->capture_interleave_skip, 0, sizeof (unsigned long *) * driver->capture_nchannels); } driver->clock_sync_data = (ClockSyncStatus *) malloc (sizeof (ClockSyncStatus) * driver->max_nchannels); driver->period_usecs = (jack_time_t) floor ((((float) driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f); driver->poll_timeout = (int) floor (1.5f * driver->period_usecs); // JACK2 /* if (driver->engine) { if (driver->engine->set_buffer_size (driver->engine, driver->frames_per_cycle)) { jack_error ("ALSA: Cannot set engine buffer size to %d (check MIDI)", driver->frames_per_cycle); return -1; } } */ return 0; } int alsa_driver_reset_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cycle, jack_nframes_t user_nperiods, jack_nframes_t rate) { /* XXX unregister old ports ? */ alsa_driver_release_channel_dependent_memory (driver); return alsa_driver_set_parameters (driver, frames_per_cycle, user_nperiods, rate); } static int alsa_driver_get_channel_addresses (alsa_driver_t *driver, snd_pcm_uframes_t *capture_avail, snd_pcm_uframes_t *playback_avail, snd_pcm_uframes_t *capture_offset, snd_pcm_uframes_t *playback_offset) { int err; channel_t chn; if (capture_avail) { if ((err = snd_pcm_mmap_begin ( driver->capture_handle, &driver->capture_areas, (snd_pcm_uframes_t *) capture_offset, (snd_pcm_uframes_t *) capture_avail)) < 0) { jack_error ("ALSA: %s: mmap areas info error", driver->alsa_name_capture); return -1; } for (chn = 0; chn < driver->capture_nchannels; chn++) { const snd_pcm_channel_area_t *a = &driver->capture_areas[chn]; driver->capture_addr[chn] = (char *) a->addr + ((a->first + a->step * *capture_offset) / 8); driver->capture_interleave_skip[chn] = (unsigned long ) (a->step / 8); } } if (playback_avail) { if ((err = snd_pcm_mmap_begin ( driver->playback_handle, &driver->playback_areas, (snd_pcm_uframes_t *) playback_offset, (snd_pcm_uframes_t *) playback_avail)) < 0) { jack_error ("ALSA: %s: mmap areas info error ", driver->alsa_name_playback); return -1; } for (chn = 0; chn < driver->playback_nchannels; chn++) { const snd_pcm_channel_area_t *a = &driver->playback_areas[chn]; driver->playback_addr[chn] = (char *) a->addr + ((a->first + a->step * *playback_offset) / 8); driver->playback_interleave_skip[chn] = (unsigned long ) (a->step / 8); } } return 0; } int alsa_driver_start (alsa_driver_t *driver) { int err; snd_pcm_uframes_t poffset, pavail; channel_t chn; driver->poll_last = 0; driver->poll_next = 0; if (driver->playback_handle) { if ((err = snd_pcm_prepare (driver->playback_handle)) < 0) { jack_error ("ALSA: prepare error for playback on " "\"%s\" (%s)", driver->alsa_name_playback, snd_strerror(err)); return -1; } } if ((driver->capture_handle && driver->capture_and_playback_not_synced) || !driver->playback_handle) { if ((err = snd_pcm_prepare (driver->capture_handle)) < 0) { jack_error ("ALSA: prepare error for capture on \"%s\"" " (%s)", driver->alsa_name_capture, snd_strerror(err)); return -1; } } if (driver->hw_monitoring) { if (driver->input_monitor_mask || driver->all_monitor_in) { if (driver->all_monitor_in) { driver->hw->set_input_monitor_mask (driver->hw, ~0U); } else { driver->hw->set_input_monitor_mask ( driver->hw, driver->input_monitor_mask); } } else { driver->hw->set_input_monitor_mask (driver->hw, driver->input_monitor_mask); } } if (driver->playback_handle) { driver->playback_nfds = snd_pcm_poll_descriptors_count (driver->playback_handle); } else { driver->playback_nfds = 0; } if (driver->capture_handle) { driver->capture_nfds = snd_pcm_poll_descriptors_count (driver->capture_handle); } else { driver->capture_nfds = 0; } if (driver->pfd) { free (driver->pfd); } driver->pfd = (struct pollfd *) malloc (sizeof (struct pollfd) * (driver->playback_nfds + driver->capture_nfds + 2)); if (driver->midi && !driver->xrun_recovery) (driver->midi->start)(driver->midi); if (driver->playback_handle) { /* fill playback buffer with zeroes, and mark all fragments as having data. */ pavail = snd_pcm_avail_update (driver->playback_handle); if (pavail != driver->frames_per_cycle * driver->playback_nperiods) { jack_error ("ALSA: full buffer not available at start"); return -1; } if (alsa_driver_get_channel_addresses (driver, 0, &pavail, 0, &poffset)) { return -1; } /* XXX this is cheating. ALSA offers no guarantee that we can access the entire buffer at any one time. It works on most hardware tested so far, however, buts its a liability in the long run. I think that alsa-lib may have a better function for doing this here, where the goal is to silence the entire buffer. */ for (chn = 0; chn < driver->playback_nchannels; chn++) { alsa_driver_silence_on_channel ( driver, chn, driver->user_nperiods * driver->frames_per_cycle); } snd_pcm_mmap_commit (driver->playback_handle, poffset, driver->user_nperiods * driver->frames_per_cycle); if ((err = snd_pcm_start (driver->playback_handle)) < 0) { jack_error ("ALSA: could not start playback (%s)", snd_strerror (err)); return -1; } } if ((driver->capture_handle && driver->capture_and_playback_not_synced) || !driver->playback_handle) { if ((err = snd_pcm_start (driver->capture_handle)) < 0) { jack_error ("ALSA: could not start capture (%s)", snd_strerror (err)); return -1; } } return 0; } int alsa_driver_stop (alsa_driver_t *driver) { int err; // JSList* node; // int chn; /* silence all capture port buffers, because we might be entering offline mode. */ // JACK2 /* for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { jack_port_t* port; char* buf; jack_nframes_t nframes = driver->engine->control->buffer_size; port = (jack_port_t *) node->data; buf = jack_port_get_buffer (port, nframes); memset (buf, 0, sizeof (jack_default_audio_sample_t) * nframes); } */ // JACK2 ClearOutput(); if (driver->playback_handle) { if ((err = snd_pcm_drop (driver->playback_handle)) < 0) { jack_error ("ALSA: channel flush for playback " "failed (%s)", snd_strerror (err)); return -1; } } if (!driver->playback_handle || driver->capture_and_playback_not_synced) { if (driver->capture_handle) { if ((err = snd_pcm_drop (driver->capture_handle)) < 0) { jack_error ("ALSA: channel flush for " "capture failed (%s)", snd_strerror (err)); return -1; } } } if (driver->hw_monitoring) { driver->hw->set_input_monitor_mask (driver->hw, 0); } if (driver->midi && !driver->xrun_recovery) (driver->midi->stop)(driver->midi); return 0; } static int alsa_driver_restart (alsa_driver_t *driver) { int res; driver->xrun_recovery = 1; // JACK2 /* if ((res = driver->nt_stop((struct _jack_driver_nt *) driver))==0) res = driver->nt_start((struct _jack_driver_nt *) driver); */ res = Restart(); driver->xrun_recovery = 0; if (res && driver->midi) (driver->midi->stop)(driver->midi); return res; } static int alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs) { snd_pcm_status_t *status; int res; snd_pcm_status_alloca(&status); if (driver->capture_handle) { if ((res = snd_pcm_status(driver->capture_handle, status)) < 0) { jack_error("status error: %s", snd_strerror(res)); } } else { if ((res = snd_pcm_status(driver->playback_handle, status)) < 0) { jack_error("status error: %s", snd_strerror(res)); } } if (snd_pcm_status_get_state(status) == SND_PCM_STATE_SUSPENDED) { jack_log("**** alsa_pcm: pcm in suspended state, resuming it" ); if (driver->capture_handle) { if ((res = snd_pcm_prepare(driver->capture_handle)) < 0) { jack_error("error preparing after suspend: %s", snd_strerror(res)); } } else { if ((res = snd_pcm_prepare(driver->playback_handle)) < 0) { jack_error("error preparing after suspend: %s", snd_strerror(res)); } } } if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN && driver->process_count > XRUN_REPORT_DELAY) { struct timeval now, diff, tstamp; driver->xrun_count++; snd_pcm_status_get_tstamp(status,&now); snd_pcm_status_get_trigger_tstamp(status, &tstamp); timersub(&now, &tstamp, &diff); *delayed_usecs = diff.tv_sec * 1000000.0 + diff.tv_usec; jack_log("**** alsa_pcm: xrun of at least %.3f msecs",*delayed_usecs / 1000.0); } if (alsa_driver_restart (driver)) { return -1; } return 0; } void alsa_driver_silence_untouched_channels (alsa_driver_t *driver, jack_nframes_t nframes) { channel_t chn; jack_nframes_t buffer_frames = driver->frames_per_cycle * driver->playback_nperiods; for (chn = 0; chn < driver->playback_nchannels; chn++) { if (bitset_contains (driver->channels_not_done, chn)) { if (driver->silent[chn] < buffer_frames) { alsa_driver_silence_on_channel_no_mark ( driver, chn, nframes); driver->silent[chn] += nframes; } } } } void alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn, ClockSyncStatus status) { driver->clock_sync_data[chn] = status; alsa_driver_clock_sync_notify (driver, chn, status); } static int under_gdb = FALSE; jack_nframes_t alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delayed_usecs) { snd_pcm_sframes_t avail = 0; snd_pcm_sframes_t capture_avail = 0; snd_pcm_sframes_t playback_avail = 0; int xrun_detected = FALSE; int need_capture; int need_playback; unsigned int i; jack_time_t poll_enter; jack_time_t poll_ret = 0; *status = -1; *delayed_usecs = 0; need_capture = driver->capture_handle ? 1 : 0; if (extra_fd >= 0) { need_playback = 0; } else { need_playback = driver->playback_handle ? 1 : 0; } again: while (need_playback || need_capture) { int poll_result; unsigned int ci = 0; unsigned int nfds; unsigned short revents; nfds = 0; if (need_playback) { snd_pcm_poll_descriptors (driver->playback_handle, &driver->pfd[0], driver->playback_nfds); nfds += driver->playback_nfds; } if (need_capture) { snd_pcm_poll_descriptors (driver->capture_handle, &driver->pfd[nfds], driver->capture_nfds); ci = nfds; nfds += driver->capture_nfds; } /* ALSA doesn't set POLLERR in some versions of 0.9.X */ for (i = 0; i < nfds; i++) { driver->pfd[i].events |= POLLERR; } if (extra_fd >= 0) { driver->pfd[nfds].fd = extra_fd; driver->pfd[nfds].events = POLLIN|POLLERR|POLLHUP|POLLNVAL; nfds++; } poll_enter = jack_get_microseconds (); if (poll_enter > driver->poll_next) { /* * This processing cycle was delayed past the * next due interrupt! Do not account this as * a wakeup delay: */ driver->poll_next = 0; driver->poll_late++; } #ifdef __ANDROID__ poll_result = poll (driver->pfd, nfds, -1); //fix for sleep issue #else poll_result = poll (driver->pfd, nfds, driver->poll_timeout); #endif if (poll_result < 0) { if (errno == EINTR) { jack_info ("poll interrupt"); // this happens mostly when run // under gdb, or when exiting due to a signal if (under_gdb) { goto again; } *status = -2; return 0; } jack_error ("ALSA: poll call failed (%s)", strerror (errno)); *status = -3; return 0; } poll_ret = jack_get_microseconds (); // JACK2 SetTime(poll_ret); if (extra_fd < 0) { if (driver->poll_next && poll_ret > driver->poll_next) { *delayed_usecs = poll_ret - driver->poll_next; } driver->poll_last = poll_ret; driver->poll_next = poll_ret + driver->period_usecs; // JACK2 /* driver->engine->transport_cycle_start (driver->engine, poll_ret); */ } #ifdef DEBUG_WAKEUP fprintf (stderr, "%" PRIu64 ": checked %d fds, started at %" PRIu64 " %" PRIu64 " usecs since poll entered\n", poll_ret, nfds, poll_enter, poll_ret - poll_enter); #endif /* check to see if it was the extra FD that caused us * to return from poll */ if (extra_fd >= 0) { if (driver->pfd[nfds-1].revents == 0) { /* we timed out on the extra fd */ *status = -4; return -1; } /* if POLLIN was the only bit set, we're OK */ *status = 0; return (driver->pfd[nfds-1].revents == POLLIN) ? 0 : -1; } if (need_playback) { if (snd_pcm_poll_descriptors_revents (driver->playback_handle, &driver->pfd[0], driver->playback_nfds, &revents) < 0) { jack_error ("ALSA: playback revents failed"); *status = -6; return 0; } if (revents & POLLERR) { xrun_detected = TRUE; } if (revents & POLLOUT) { need_playback = 0; #ifdef DEBUG_WAKEUP fprintf (stderr, "%" PRIu64 " playback stream ready\n", poll_ret); #endif } } if (need_capture) { if (snd_pcm_poll_descriptors_revents (driver->capture_handle, &driver->pfd[ci], driver->capture_nfds, &revents) < 0) { jack_error ("ALSA: capture revents failed"); *status = -6; return 0; } if (revents & POLLERR) { xrun_detected = TRUE; } if (revents & POLLIN) { need_capture = 0; #ifdef DEBUG_WAKEUP fprintf (stderr, "%" PRIu64 " capture stream ready\n", poll_ret); #endif } } if (poll_result == 0) { jack_error ("ALSA: poll time out, polled for %" PRIu64 " usecs", poll_ret - poll_enter); *status = -5; return 0; } } if (driver->capture_handle) { if ((capture_avail = snd_pcm_avail_update ( driver->capture_handle)) < 0) { if (capture_avail == -EPIPE) { xrun_detected = TRUE; } else { jack_error ("unknown ALSA avail_update return" " value (%u)", capture_avail); } } } else { /* odd, but see min() computation below */ capture_avail = INT_MAX; } if (driver->playback_handle) { if ((playback_avail = snd_pcm_avail_update ( driver->playback_handle)) < 0) { if (playback_avail == -EPIPE) { xrun_detected = TRUE; } else { jack_error ("unknown ALSA avail_update return" " value (%u)", playback_avail); } } } else { /* odd, but see min() computation below */ playback_avail = INT_MAX; } if (xrun_detected) { *status = alsa_driver_xrun_recovery (driver, delayed_usecs); return 0; } *status = 0; driver->last_wait_ust = poll_ret; avail = capture_avail < playback_avail ? capture_avail : playback_avail; #ifdef DEBUG_WAKEUP fprintf (stderr, "wakeup complete, avail = %lu, pavail = %lu " "cavail = %lu\n", avail, playback_avail, capture_avail); #endif /* mark all channels not done for now. read/write will change this */ bitset_copy (driver->channels_not_done, driver->channels_done); /* constrain the available count to the nearest (round down) number of periods. */ return avail - (avail % driver->frames_per_cycle); } int alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) { snd_pcm_sframes_t contiguous; snd_pcm_sframes_t nread; snd_pcm_uframes_t offset; jack_nframes_t orig_nframes; // jack_default_audio_sample_t* buf; // channel_t chn; // JSList *node; // jack_port_t* port; int err; if (nframes > driver->frames_per_cycle) { return -1; } // JACK2 /* if (driver->engine->freewheeling) { return 0; } */ if (driver->midi) (driver->midi->read)(driver->midi, nframes); if (!driver->capture_handle) { return 0; } nread = 0; contiguous = 0; orig_nframes = nframes; while (nframes) { contiguous = nframes; if (alsa_driver_get_channel_addresses ( driver, (snd_pcm_uframes_t *) &contiguous, (snd_pcm_uframes_t *) 0, &offset, 0) < 0) { return -1; } // JACK2 /* for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { port = (jack_port_t *) node->data; if (!jack_port_connected (port)) { // no-copy optimization continue; } buf = jack_port_get_buffer (port, orig_nframes); alsa_driver_read_from_channel (driver, chn, buf + nread, contiguous); } */ ReadInput(orig_nframes, contiguous, nread); if ((err = snd_pcm_mmap_commit (driver->capture_handle, offset, contiguous)) < 0) { jack_error ("ALSA: could not complete read of %" PRIu32 " frames: error = %d", contiguous, err); return -1; } nframes -= contiguous; nread += contiguous; } return 0; } int alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) { // channel_t chn; // JSList *node; // JSList *mon_node; // jack_default_audio_sample_t* buf; // jack_default_audio_sample_t* monbuf; jack_nframes_t orig_nframes; snd_pcm_sframes_t nwritten; snd_pcm_sframes_t contiguous; snd_pcm_uframes_t offset; // jack_port_t *port; int err; driver->process_count++; // JACK2 /* if (!driver->playback_handle || driver->engine->freewheeling) { return 0; } */ if (!driver->playback_handle) { return 0; } if (nframes > driver->frames_per_cycle) { return -1; } if (driver->midi) (driver->midi->write)(driver->midi, nframes); nwritten = 0; contiguous = 0; orig_nframes = nframes; /* check current input monitor request status */ driver->input_monitor_mask = 0; // JACK2 /* for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { if (((jack_port_t *) node->data)->shared->monitor_requests) { driver->input_monitor_mask |= (1<hw_monitoring) { if ((driver->hw->input_monitor_mask != driver->input_monitor_mask) && !driver->all_monitor_in) { driver->hw->set_input_monitor_mask ( driver->hw, driver->input_monitor_mask); } } while (nframes) { contiguous = nframes; if (alsa_driver_get_channel_addresses ( driver, (snd_pcm_uframes_t *) 0, (snd_pcm_uframes_t *) &contiguous, 0, &offset) < 0) { return -1; } // JACK2 /* for (chn = 0, node = driver->playback_ports, mon_node=driver->monitor_ports; node; node = jack_slist_next (node), chn++) { port = (jack_port_t *) node->data; if (!jack_port_connected (port)) { continue; } buf = jack_port_get_buffer (port, orig_nframes); alsa_driver_write_to_channel (driver, chn, buf + nwritten, contiguous); if (mon_node) { port = (jack_port_t *) mon_node->data; if (!jack_port_connected (port)) { continue; } monbuf = jack_port_get_buffer (port, orig_nframes); memcpy (monbuf + nwritten, buf + nwritten, contiguous * sizeof(jack_default_audio_sample_t)); mon_node = jack_slist_next (mon_node); } } */ // JACK2 WriteOutput(orig_nframes, contiguous, nwritten); if (!bitset_empty (driver->channels_not_done)) { alsa_driver_silence_untouched_channels (driver, contiguous); } if ((err = snd_pcm_mmap_commit (driver->playback_handle, offset, contiguous)) < 0) { jack_error ("ALSA: could not complete playback of %" PRIu32 " frames: error = %d", contiguous, err); if (err != -EPIPE && err != -ESTRPIPE) return -1; } nframes -= contiguous; nwritten += contiguous; } return 0; } #if 0 static int /* UNUSED */ alsa_driver_change_sample_clock (alsa_driver_t *driver, SampleClockMode mode) { return driver->hw->change_sample_clock (driver->hw, mode); } static void /* UNUSED */ alsa_driver_request_all_monitor_input (alsa_driver_t *driver, int yn) { if (driver->hw_monitoring) { if (yn) { driver->hw->set_input_monitor_mask (driver->hw, ~0U); } else { driver->hw->set_input_monitor_mask ( driver->hw, driver->input_monitor_mask); } } driver->all_monitor_in = yn; } static void /* UNUSED */ alsa_driver_set_hw_monitoring (alsa_driver_t *driver, int yn) { if (yn) { driver->hw_monitoring = TRUE; if (driver->all_monitor_in) { driver->hw->set_input_monitor_mask (driver->hw, ~0U); } else { driver->hw->set_input_monitor_mask ( driver->hw, driver->input_monitor_mask); } } else { driver->hw_monitoring = FALSE; driver->hw->set_input_monitor_mask (driver->hw, 0); } } static ClockSyncStatus /* UNUSED */ alsa_driver_clock_sync_status (channel_t chn) { return Lock; } #endif void alsa_driver_delete (alsa_driver_t *driver) { JSList *node; if (driver->midi) (driver->midi->destroy)(driver->midi); for (node = driver->clock_sync_listeners; node; node = jack_slist_next (node)) { free (node->data); } jack_slist_free (driver->clock_sync_listeners); if (driver->ctl_handle) { snd_ctl_close (driver->ctl_handle); driver->ctl_handle = 0; } if (driver->capture_handle) { snd_pcm_close (driver->capture_handle); driver->capture_handle = 0; } if (driver->playback_handle) { snd_pcm_close (driver->playback_handle); driver->capture_handle = 0; } if (driver->capture_hw_params) { snd_pcm_hw_params_free (driver->capture_hw_params); driver->capture_hw_params = 0; } if (driver->playback_hw_params) { snd_pcm_hw_params_free (driver->playback_hw_params); driver->playback_hw_params = 0; } if (driver->capture_sw_params) { snd_pcm_sw_params_free (driver->capture_sw_params); driver->capture_sw_params = 0; } if (driver->playback_sw_params) { snd_pcm_sw_params_free (driver->playback_sw_params); driver->playback_sw_params = 0; } if (driver->pfd) { free (driver->pfd); } if (driver->hw) { driver->hw->release (driver->hw); driver->hw = 0; } free(driver->alsa_name_playback); free(driver->alsa_name_capture); free(driver->alsa_driver); alsa_driver_release_channel_dependent_memory (driver); //JACK2 //jack_driver_nt_finish ((jack_driver_nt_t *) driver); free (driver); } static char* discover_alsa_using_apps () { char found[2048]; char command[5192]; char* path = getenv ("PATH"); char* dir; size_t flen = 0; int card; int device; size_t cmdlen = 0; if (!path) { return NULL; } /* look for lsof and give up if its not in PATH */ path = strdup (path); dir = strtok (path, ":"); while (dir) { char maybe[PATH_MAX+1]; snprintf (maybe, sizeof(maybe), "%s/lsof", dir); if (access (maybe, X_OK)) { break; } dir = strtok (NULL, ":"); } free (path); if (!dir) { return NULL; } snprintf (command, sizeof (command), "lsof -Fc0 "); cmdlen = strlen (command); for (card = 0; card < 8; ++card) { for (device = 0; device < 8; ++device) { char buf[32]; snprintf (buf, sizeof (buf), "/dev/snd/pcmC%dD%dp", card, device); if (access (buf, F_OK) == 0) { snprintf (command+cmdlen, sizeof(command)-cmdlen, "%s ", buf); } cmdlen = strlen (command); snprintf (buf, sizeof (buf), "/dev/snd/pcmC%dD%dc", card, device); if (access (buf, F_OK) == 0) { snprintf (command+cmdlen, sizeof(command)-cmdlen, "%s ", buf); } cmdlen = strlen (command); } } FILE* f = popen (command, "r"); if (!f) { return NULL; } while (!feof (f)) { char buf[1024]; /* lsof doesn't output much */ if (!fgets (buf, sizeof (buf), f)) { break; } if (*buf != 'p') { return NULL; } /* buf contains NULL as a separator between the process field and the command field */ char *pid = buf; ++pid; /* skip leading 'p' */ char *cmd = pid; /* skip to NULL */ while (*cmd) { ++cmd; } ++cmd; /* skip to 'c' */ ++cmd; /* skip to first character of command */ snprintf (found+flen, sizeof (found)-flen, "%s (process ID %s)\n", cmd, pid); flen = strlen (found); if (flen >= sizeof (found)) { break; } } pclose (f); if (flen) { return strdup (found); } else { return NULL; } } jack_driver_t * alsa_driver_new (char *name, char *playback_alsa_device, char *capture_alsa_device, jack_client_t *client, jack_nframes_t frames_per_cycle, jack_nframes_t user_nperiods, jack_nframes_t rate, int hw_monitoring, int hw_metering, int capturing, int playing, DitherAlgorithm dither, int soft_mode, int monitor, int user_capture_nchnls, int user_playback_nchnls, int shorts_first, jack_nframes_t capture_latency, jack_nframes_t playback_latency, alsa_midi_t *midi_driver ) { int err; char* current_apps; alsa_driver_t *driver; jack_info ("creating alsa driver ... %s|%s|%" PRIu32 "|%" PRIu32 "|%" PRIu32"|%" PRIu32"|%" PRIu32 "|%s|%s|%s|%s", playing ? playback_alsa_device : "-", capturing ? capture_alsa_device : "-", frames_per_cycle, user_nperiods, rate, user_capture_nchnls,user_playback_nchnls, hw_monitoring ? "hwmon": "nomon", hw_metering ? "hwmeter":"swmeter", soft_mode ? "soft-mode":"-", shorts_first ? "16bit":"32bit"); driver = (alsa_driver_t *) calloc (1, sizeof (alsa_driver_t)); jack_driver_nt_init ((jack_driver_nt_t *) driver); // JACK2 /* driver->nt_attach = (JackDriverNTAttachFunction) alsa_driver_attach; driver->nt_detach = (JackDriverNTDetachFunction) alsa_driver_detach; driver->read = (JackDriverReadFunction) alsa_driver_read; driver->write = (JackDriverReadFunction) alsa_driver_write; driver->null_cycle = (JackDriverNullCycleFunction) alsa_driver_null_cycle; driver->nt_bufsize = (JackDriverNTBufSizeFunction) alsa_driver_bufsize; driver->nt_start = (JackDriverNTStartFunction) alsa_driver_start; driver->nt_stop = (JackDriverNTStopFunction) alsa_driver_stop; driver->nt_run_cycle = (JackDriverNTRunCycleFunction) alsa_driver_run_cycle; */ driver->playback_handle = NULL; driver->capture_handle = NULL; driver->ctl_handle = 0; driver->hw = 0; driver->capture_and_playback_not_synced = FALSE; driver->max_nchannels = 0; driver->user_nchannels = 0; driver->playback_nchannels = user_playback_nchnls; driver->capture_nchannels = user_capture_nchnls; driver->playback_sample_bytes = (shorts_first ? 2:4); driver->capture_sample_bytes = (shorts_first ? 2:4); driver->capture_frame_latency = capture_latency; driver->playback_frame_latency = playback_latency; driver->playback_addr = 0; driver->capture_addr = 0; driver->playback_interleave_skip = NULL; driver->capture_interleave_skip = NULL; driver->silent = 0; driver->all_monitor_in = FALSE; driver->with_monitor_ports = monitor; driver->clock_mode = ClockMaster; /* XXX is it? */ driver->input_monitor_mask = 0; /* XXX is it? */ driver->capture_ports = 0; driver->playback_ports = 0; driver->monitor_ports = 0; driver->pfd = 0; driver->playback_nfds = 0; driver->capture_nfds = 0; driver->dither = dither; driver->soft_mode = soft_mode; driver->quirk_bswap = 0; pthread_mutex_init (&driver->clock_sync_lock, 0); driver->clock_sync_listeners = 0; driver->poll_late = 0; driver->xrun_count = 0; driver->process_count = 0; driver->alsa_name_playback = strdup (playback_alsa_device); driver->alsa_name_capture = strdup (capture_alsa_device); driver->midi = midi_driver; driver->xrun_recovery = 0; if (alsa_driver_check_card_type (driver)) { alsa_driver_delete (driver); return NULL; } alsa_driver_hw_specific (driver, hw_monitoring, hw_metering); if (playing) { if (snd_pcm_open (&driver->playback_handle, playback_alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) { switch (errno) { case EBUSY: #ifdef __ANDROID__ jack_error ("\n\nATTENTION: The playback device \"%s\" is " "already in use. Please stop the" " application using it and " "run JACK again", playback_alsa_device); #else current_apps = discover_alsa_using_apps (); if (current_apps) { jack_error ("\n\nATTENTION: The playback device \"%s\" is " "already in use. The following applications " " are using your soundcard(s) so you should " " check them and stop them as necessary before " " trying to start JACK again:\n\n%s", playback_alsa_device, current_apps); free (current_apps); } else { jack_error ("\n\nATTENTION: The playback device \"%s\" is " "already in use. Please stop the" " application using it and " "run JACK again", playback_alsa_device); } #endif alsa_driver_delete (driver); return NULL; case EPERM: jack_error ("you do not have permission to open " "the audio device \"%s\" for playback", playback_alsa_device); alsa_driver_delete (driver); return NULL; break; } driver->playback_handle = NULL; } if (driver->playback_handle) { snd_pcm_nonblock (driver->playback_handle, 0); } } if (capturing) { if (snd_pcm_open (&driver->capture_handle, capture_alsa_device, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK) < 0) { switch (errno) { case EBUSY: #ifdef __ANDROID__ jack_error ("\n\nATTENTION: The capture (recording) device \"%s\" is " "already in use", capture_alsa_device); #else current_apps = discover_alsa_using_apps (); if (current_apps) { jack_error ("\n\nATTENTION: The capture device \"%s\" is " "already in use. The following applications " " are using your soundcard(s) so you should " " check them and stop them as necessary before " " trying to start JACK again:\n\n%s", capture_alsa_device, current_apps); free (current_apps); } else { jack_error ("\n\nATTENTION: The capture (recording) device \"%s\" is " "already in use. Please stop the" " application using it and " "run JACK again", capture_alsa_device); } alsa_driver_delete (driver); return NULL; #endif break; case EPERM: jack_error ("you do not have permission to open " "the audio device \"%s\" for capture", capture_alsa_device); alsa_driver_delete (driver); return NULL; break; } driver->capture_handle = NULL; } if (driver->capture_handle) { snd_pcm_nonblock (driver->capture_handle, 0); } } if (driver->playback_handle == NULL) { if (playing) { /* they asked for playback, but we can't do it */ jack_error ("ALSA: Cannot open PCM device %s for " "playback. Falling back to capture-only" " mode", name); if (driver->capture_handle == NULL) { /* can't do anything */ alsa_driver_delete (driver); return NULL; } playing = FALSE; } } if (driver->capture_handle == NULL) { if (capturing) { /* they asked for capture, but we can't do it */ jack_error ("ALSA: Cannot open PCM device %s for " "capture. Falling back to playback-only" " mode", name); if (driver->playback_handle == NULL) { /* can't do anything */ alsa_driver_delete (driver); return NULL; } capturing = FALSE; } } driver->playback_hw_params = 0; driver->capture_hw_params = 0; driver->playback_sw_params = 0; driver->capture_sw_params = 0; if (driver->playback_handle) { if ((err = snd_pcm_hw_params_malloc ( &driver->playback_hw_params)) < 0) { jack_error ("ALSA: could not allocate playback hw" " params structure"); alsa_driver_delete (driver); return NULL; } if ((err = snd_pcm_sw_params_malloc ( &driver->playback_sw_params)) < 0) { jack_error ("ALSA: could not allocate playback sw" " params structure"); alsa_driver_delete (driver); return NULL; } } if (driver->capture_handle) { if ((err = snd_pcm_hw_params_malloc ( &driver->capture_hw_params)) < 0) { jack_error ("ALSA: could not allocate capture hw" " params structure"); alsa_driver_delete (driver); return NULL; } if ((err = snd_pcm_sw_params_malloc ( &driver->capture_sw_params)) < 0) { jack_error ("ALSA: could not allocate capture sw" " params structure"); alsa_driver_delete (driver); return NULL; } } if (alsa_driver_set_parameters (driver, frames_per_cycle, user_nperiods, rate)) { alsa_driver_delete (driver); return NULL; } driver->capture_and_playback_not_synced = FALSE; if (driver->capture_handle && driver->playback_handle) { if (snd_pcm_link (driver->playback_handle, driver->capture_handle) != 0) { driver->capture_and_playback_not_synced = TRUE; } } driver->client = client; return (jack_driver_t *) driver; } int alsa_driver_listen_for_clock_sync_status (alsa_driver_t *driver, ClockSyncListenerFunction func, void *arg) { ClockSyncListener *csl; csl = (ClockSyncListener *) malloc (sizeof (ClockSyncListener)); csl->function = func; csl->arg = arg; csl->id = driver->next_clock_sync_listener_id++; pthread_mutex_lock (&driver->clock_sync_lock); driver->clock_sync_listeners = jack_slist_prepend (driver->clock_sync_listeners, csl); pthread_mutex_unlock (&driver->clock_sync_lock); return csl->id; } int alsa_driver_stop_listening_to_clock_sync_status (alsa_driver_t *driver, unsigned int which) { JSList *node; int ret = -1; pthread_mutex_lock (&driver->clock_sync_lock); for (node = driver->clock_sync_listeners; node; node = jack_slist_next (node)) { if (((ClockSyncListener *) node->data)->id == which) { driver->clock_sync_listeners = jack_slist_remove_link ( driver->clock_sync_listeners, node); free (node->data); jack_slist_free_1 (node); ret = 0; break; } } pthread_mutex_unlock (&driver->clock_sync_lock); return ret; } void alsa_driver_clock_sync_notify (alsa_driver_t *driver, channel_t chn, ClockSyncStatus status) { JSList *node; pthread_mutex_lock (&driver->clock_sync_lock); for (node = driver->clock_sync_listeners; node; node = jack_slist_next (node)) { ClockSyncListener *csl = (ClockSyncListener *) node->data; csl->function (chn, status, csl->arg); } pthread_mutex_unlock (&driver->clock_sync_lock); } /* DRIVER "PLUGIN" INTERFACE */ const char driver_client_name[] = "alsa_pcm"; void driver_finish (jack_driver_t *driver) { alsa_driver_delete ((alsa_driver_t *) driver); } 1.9.12~dfsg/linux/alsa/alsa_midi.h0000644000000000000000000000300013214314510015503 0ustar rootroot/* * Copyright (c) 2006 Dmitry S. Baikov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __jack_alsa_midi_h__ #define __jack_alsa_midi_h__ #ifdef __cplusplus extern "C" { #else #include #endif typedef struct alsa_midi_t alsa_midi_t; struct alsa_midi_t { void (*destroy)(alsa_midi_t *amidi); int (*attach)(alsa_midi_t *amidi); int (*detach)(alsa_midi_t *amidi); int (*start)(alsa_midi_t *amidi); int (*stop)(alsa_midi_t *amidi); void (*read)(alsa_midi_t *amidi, jack_nframes_t nframes); void (*write)(alsa_midi_t *amidi, jack_nframes_t nframes); }; alsa_midi_t* alsa_rawmidi_new(jack_client_t *jack); alsa_midi_t* alsa_seqmidi_new(jack_client_t *jack, const char* alsa_name); #ifdef __cplusplus } // extern "C" #endif #endif /* __jack_alsa_midi_h__ */ 1.9.12~dfsg/linux/alsa/JackAlsaDriver.h0000644000000000000000000000644213214314510016423 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackAlsaDriver__ #define __JackAlsaDriver__ #include "JackAudioDriver.h" #include "JackThreadedDriver.h" #include "JackTime.h" #include "alsa_driver.h" namespace Jack { /*! \brief The ALSA driver. */ class JackAlsaDriver : public JackAudioDriver { private: jack_driver_t* fDriver; void UpdateLatencies(); public: JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table),fDriver(NULL) {} virtual ~JackAlsaDriver() {} int Open(jack_nframes_t buffer_size, jack_nframes_t user_nperiods, jack_nframes_t samplerate, bool hw_monitoring, bool hw_metering, bool capturing, bool playing, DitherAlgorithm dither, bool soft_mode, bool monitor, int inchannels, int outchannels, bool shorts_first, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, const char* midi_driver_name); int Close(); int Attach(); int Detach(); int Start(); int Stop(); int Read(); int Write(); // BufferSize can be changed bool IsFixedBufferSize() { return false; } int SetBufferSize(jack_nframes_t buffer_size); void ReadInputAux(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nread); void MonitorInputAux(); void ClearOutputAux(); void WriteOutputAux(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten); void SetTimetAux(jack_time_t time); // JACK API emulation for the midi driver int is_realtime() const; int create_thread(pthread_t *thread, int prio, int rt, void *(*start_func)(void*), void *arg); jack_port_id_t port_register(const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size); int port_unregister(jack_port_id_t port_index); void* port_get_buffer(int port, jack_nframes_t nframes); int port_set_alias(int port, const char* name); jack_nframes_t get_sample_rate() const; jack_nframes_t frame_time() const; jack_nframes_t last_frame_time() const; }; } // end of namespace #endif 1.9.12~dfsg/linux/alsa/bitset.h0000644000000000000000000000674213214314510015073 0ustar rootroot/* * bitset.h -- some simple bit vector set operations. * * This is useful for sets of small non-negative integers. There are * some obvious set operations that are not implemented because I * don't need them right now. * * These functions represent sets as arrays of unsigned 32-bit * integers allocated on the heap. The first entry contains the set * cardinality (number of elements allowed), followed by one or more * words containing bit vectors. * * $Id: bitset.h,v 1.2 2005/11/23 11:24:29 letz Exp $ */ /* * Copyright (C) 2005 Jack O'Quin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __bitset_h__ #define __bitset_h__ #include /* POSIX standard fixed-size types */ #include /* `#define NDEBUG' to disable */ /* On some 64-bit machines, this implementation may be slightly * inefficient, depending on how compilers allocate space for * uint32_t. For the set sizes I currently need, this is acceptable. * It should not be hard to pack the bits better, if that becomes * worthwhile. */ typedef uint32_t _bitset_word_t; typedef _bitset_word_t *bitset_t; #define WORD_SIZE(cardinality) (1+((cardinality)+31)/32) #define BYTE_SIZE(cardinality) (WORD_SIZE(cardinality)*sizeof(_bitset_word_t)) #define WORD_INDEX(element) (1+(element)/32) #define BIT_INDEX(element) ((element)&037) static inline void bitset_add(bitset_t set , unsigned int element) { assert(element < set [0]); set [WORD_INDEX(element)] |= (1 << BIT_INDEX(element)); } static inline void bitset_copy(bitset_t to_set, bitset_t from_set) { assert(to_set[0] == from_set[0]); memcpy(to_set, from_set, BYTE_SIZE(to_set[0])); } static inline void bitset_create(bitset_t *set , unsigned int cardinality) { *set = (bitset_t) calloc(WORD_SIZE(cardinality), sizeof(_bitset_word_t)); assert(*set ); *set [0] = cardinality; } static inline void bitset_destroy(bitset_t *set ) { if (*set ) { free(*set ); *set = (bitset_t) 0; } } static inline int bitset_empty(bitset_t set ) { int i; _bitset_word_t result = 0; int nwords = WORD_SIZE(set [0]); for (i = 1; i < nwords; i++) { result |= set [i]; } return (result == 0); } static inline int bitset_contains(bitset_t set , unsigned int element) { assert(element < set [0]); return (0 != (set [WORD_INDEX(element)] & (1 << BIT_INDEX(element)))); } static inline void bitset_remove(bitset_t set , unsigned int element) { assert(element < set [0]); set [WORD_INDEX(element)] &= ~(1 << BIT_INDEX(element)); } #endif /* __bitset_h__ */ 1.9.12~dfsg/linux/alsa/ice1712.c0000644000000000000000000001005713214314510014641 0ustar rootroot/* Copyright (C) 2002 Anthony Van Groningen Parts based on source code taken from the "Env24 chipset (ICE1712) control utility" that is Copyright (C) 2000 by Jaroslav Kysela This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "hardware.h" #include "alsa_driver.h" #include "ice1712.h" #include "JackError.h" static int ice1712_hw_monitor_toggle(jack_hardware_t *hw, int idx, int onoff) { ice1712_t *h = (ice1712_t *) hw->private_hw; snd_ctl_elem_value_t *val; int err; snd_ctl_elem_value_alloca (&val); snd_ctl_elem_value_set_interface (val, SND_CTL_ELEM_IFACE_MIXER); if (idx >= 8) { snd_ctl_elem_value_set_name (val, SPDIF_PLAYBACK_ROUTE_NAME); snd_ctl_elem_value_set_index (val, idx - 8); } else { snd_ctl_elem_value_set_name (val, ANALOG_PLAYBACK_ROUTE_NAME); snd_ctl_elem_value_set_index (val, idx); } if (onoff) { snd_ctl_elem_value_set_enumerated (val, 0, idx + 1); } else { snd_ctl_elem_value_set_enumerated (val, 0, 0); } if ((err = snd_ctl_elem_write (h->driver->ctl_handle, val)) != 0) { jack_error ("ALSA/ICE1712: (%d) cannot set input monitoring (%s)", idx,snd_strerror (err)); return -1; } return 0; } static int ice1712_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) { int idx; ice1712_t *h = (ice1712_t *) hw->private_hw; for (idx = 0; idx < 10; idx++) { if (h->active_channels & (1<input_monitor_mask = mask; return 0; } static int ice1712_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) { return -1; } static void ice1712_release (jack_hardware_t *hw) { ice1712_t *h = (ice1712_t *) hw->private_hw; if (h == 0) return; if (h->eeprom) free(h->eeprom); free(h); } jack_hardware_t * jack_alsa_ice1712_hw_new (alsa_driver_t *driver) { jack_hardware_t *hw; ice1712_t *h; snd_ctl_elem_value_t *val; int err; hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); hw->capabilities = Cap_HardwareMonitoring; hw->input_monitor_mask = 0; hw->private_hw = 0; hw->set_input_monitor_mask = ice1712_set_input_monitor_mask; hw->change_sample_clock = ice1712_change_sample_clock; hw->release = ice1712_release; h = (ice1712_t *) malloc (sizeof (ice1712_t)); h->driver = driver; /* Get the EEPROM (adopted from envy24control) */ h->eeprom = (ice1712_eeprom_t *) malloc (sizeof (ice1712_eeprom_t)); snd_ctl_elem_value_alloca (&val); snd_ctl_elem_value_set_interface (val, SND_CTL_ELEM_IFACE_CARD); snd_ctl_elem_value_set_name (val, "ICE1712 EEPROM"); if ((err = snd_ctl_elem_read (driver->ctl_handle, val)) < 0) { jack_error( "ALSA/ICE1712: Unable to read EEPROM contents (%s)\n", snd_strerror (err)); /* Recover? */ } memcpy(h->eeprom, snd_ctl_elem_value_get_bytes(val), 32); /* determine number of pro ADC's. We're asumming that there is at least one stereo pair. Should check this first, but how? */ switch((h->eeprom->codec & 0xCU) >> 2) { case 0: h->active_channels = 0x3U; break; case 1: h->active_channels = 0xfU; break; case 2: h->active_channels = 0x3fU; break; case 3: h->active_channels = 0xffU; break; } /* check for SPDIF In's */ if (h->eeprom->spdif & 0x1U) { h->active_channels |= 0x300U; } hw->private_hw = h; return hw; } 1.9.12~dfsg/linux/alsa/JackAlsaDriver.cpp0000644000000000000000000007554713214314510016772 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define __STDC_FORMAT_MACROS // For inttypes.h to work in C++ #include #include #include #include #include #include #include #include #include #include #include #include #include "JackAlsaDriver.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackPort.h" #include "JackGraphManager.h" #include "JackLockedEngine.h" #ifdef __ANDROID__ #include "JackAndroidThread.h" #else #include "JackPosixThread.h" #endif #include "JackCompilerDeps.h" #include "JackServerGlobals.h" static struct jack_constraint_enum_str_descriptor midi_constraint_descr_array[] = { { "none", "no MIDI driver" }, { "seq", "ALSA Sequencer driver" }, { "raw", "ALSA RawMIDI driver" }, { 0 } }; static struct jack_constraint_enum_char_descriptor dither_constraint_descr_array[] = { { 'n', "none" }, { 'r', "rectangular" }, { 's', "shaped" }, { 't', "triangular" }, { 0 } }; namespace Jack { int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size) { jack_log("JackAlsaDriver::SetBufferSize %ld", buffer_size); int res = alsa_driver_reset_parameters((alsa_driver_t *)fDriver, buffer_size, ((alsa_driver_t *)fDriver)->user_nperiods, ((alsa_driver_t *)fDriver)->frame_rate); if (res == 0) { // update fEngineControl and fGraphManager JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails // ALSA specific UpdateLatencies(); } else { // Restore old values alsa_driver_reset_parameters((alsa_driver_t *)fDriver, fEngineControl->fBufferSize, ((alsa_driver_t *)fDriver)->user_nperiods, ((alsa_driver_t *)fDriver)->frame_rate); } return res; } void JackAlsaDriver::UpdateLatencies() { jack_latency_range_t range; alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver; for (int i = 0; i < fCaptureChannels; i++) { range.min = range.max = alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency; fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); } for (int i = 0; i < fPlaybackChannels; i++) { // Add one buffer more latency if "async" mode is used... range.min = range.max = (alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency; fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); // Monitor port if (fWithMonitorPorts) { range.min = range.max = alsa_driver->frames_per_cycle; fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range); } } } int JackAlsaDriver::Attach() { JackPort* port; jack_port_id_t port_index; unsigned long port_flags = (unsigned long)CaptureDriverFlags; char name[REAL_JACK_PORT_NAME_SIZE+1]; char alias[REAL_JACK_PORT_NAME_SIZE+1]; assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver; if (alsa_driver->has_hw_monitoring) port_flags |= JackPortCanMonitor; // ALSA driver may have changed the values JackAudioDriver::SetBufferSize(alsa_driver->frames_per_cycle); JackAudioDriver::SetSampleRate(alsa_driver->frame_rate); jack_log("JackAlsaDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (int i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fCapturePortList[i] = port_index; jack_log("JackAlsaDriver::Attach fCapturePortList[i] %ld ", port_index); } port_flags = (unsigned long)PlaybackDriverFlags; for (int i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fPlaybackPortList[i] = port_index; jack_log("JackAlsaDriver::Attach fPlaybackPortList[i] %ld ", port_index); // Monitor ports if (fWithMonitorPorts) { jack_log("Create monitor port"); snprintf(name, sizeof(name), "%s:monitor_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("ALSA: cannot register monitor port for %s", name); } else { fMonitorPortList[i] = port_index; } } } UpdateLatencies(); if (alsa_driver->midi) { int err = (alsa_driver->midi->attach)(alsa_driver->midi); if (err) jack_error ("ALSA: cannot attach MIDI: %d", err); } return 0; } int JackAlsaDriver::Detach() { alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver; if (alsa_driver->midi) (alsa_driver->midi->detach)(alsa_driver->midi); return JackAudioDriver::Detach(); } extern "C" char* get_control_device_name(const char * device_name) { char * ctl_name; const char * comma; /* the user wants a hw or plughw device, the ctl name * should be hw:x where x is the card identification. * We skip the subdevice suffix that starts with comma */ if (strncasecmp(device_name, "plughw:", 7) == 0) { /* skip the "plug" prefix" */ device_name += 4; } comma = strchr(device_name, ','); if (comma == NULL) { ctl_name = strdup(device_name); if (ctl_name == NULL) { jack_error("strdup(\"%s\") failed.", device_name); } } else { ctl_name = strndup(device_name, comma - device_name); if (ctl_name == NULL) { jack_error("strndup(\"%s\", %u) failed.", device_name, (unsigned int)(comma - device_name)); } } return ctl_name; } static int card_to_num(const char* device) { int err; char* ctl_name; snd_ctl_card_info_t *card_info; snd_ctl_t* ctl_handle; int i = -1; snd_ctl_card_info_alloca (&card_info); ctl_name = get_control_device_name(device); if (ctl_name == NULL) { jack_error("get_control_device_name() failed."); goto fail; } if ((err = snd_ctl_open (&ctl_handle, ctl_name, 0)) < 0) { jack_error ("control open \"%s\" (%s)", ctl_name, snd_strerror(err)); goto free; } if ((err = snd_ctl_card_info(ctl_handle, card_info)) < 0) { jack_error ("control hardware info \"%s\" (%s)", device, snd_strerror (err)); goto close; } i = snd_ctl_card_info_get_card(card_info); close: snd_ctl_close(ctl_handle); free: free(ctl_name); fail: return i; } int JackAlsaDriver::Open(jack_nframes_t nframes, jack_nframes_t user_nperiods, jack_nframes_t samplerate, bool hw_monitoring, bool hw_metering, bool capturing, bool playing, DitherAlgorithm dither, bool soft_mode, bool monitor, int inchannels, int outchannels, bool shorts_first, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, const char* midi_driver_name) { // Generic JackAudioDriver Open if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) { return -1; } alsa_midi_t *midi = 0; #ifndef __ANDROID__ if (strcmp(midi_driver_name, "seq") == 0) midi = alsa_seqmidi_new((jack_client_t*)this, 0); else if (strcmp(midi_driver_name, "raw") == 0) midi = alsa_rawmidi_new((jack_client_t*)this); #endif if (JackServerGlobals::on_device_acquire != NULL) { int capture_card = card_to_num(capture_driver_name); int playback_card = card_to_num(playback_driver_name); char audio_name[32]; if (capture_card >= 0) { snprintf(audio_name, sizeof(audio_name), "Audio%d", capture_card); if (!JackServerGlobals::on_device_acquire(audio_name)) { jack_error("Audio device %s cannot be acquired...", capture_driver_name); return -1; } } if (playback_card >= 0 && playback_card != capture_card) { snprintf(audio_name, sizeof(audio_name), "Audio%d", playback_card); if (!JackServerGlobals::on_device_acquire(audio_name)) { jack_error("Audio device %s cannot be acquired...", playback_driver_name); if (capture_card >= 0) { snprintf(audio_name, sizeof(audio_name), "Audio%d", capture_card); JackServerGlobals::on_device_release(audio_name); } return -1; } } } fDriver = alsa_driver_new ((char*)"alsa_pcm", (char*)playback_driver_name, (char*)capture_driver_name, NULL, nframes, user_nperiods, samplerate, hw_monitoring, hw_metering, capturing, playing, dither, soft_mode, monitor, inchannels, outchannels, shorts_first, capture_latency, playback_latency, midi); if (fDriver) { // ALSA driver may have changed the in/out values fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels; fPlaybackChannels = ((alsa_driver_t *)fDriver)->playback_nchannels; return 0; } else { Close(); return -1; } } int JackAlsaDriver::Close() { // Generic audio driver close int res = JackAudioDriver::Close(); if (fDriver) { alsa_driver_delete((alsa_driver_t*)fDriver); } if (JackServerGlobals::on_device_release != NULL) { char audio_name[32]; int capture_card = card_to_num(fCaptureDriverName); if (capture_card >= 0) { snprintf(audio_name, sizeof(audio_name), "Audio%d", capture_card); JackServerGlobals::on_device_release(audio_name); } int playback_card = card_to_num(fPlaybackDriverName); if (playback_card >= 0 && playback_card != capture_card) { snprintf(audio_name, sizeof(audio_name), "Audio%d", playback_card); JackServerGlobals::on_device_release(audio_name); } } return res; } int JackAlsaDriver::Start() { int res = JackAudioDriver::Start(); if (res >= 0) { res = alsa_driver_start((alsa_driver_t *)fDriver); if (res < 0) { JackAudioDriver::Stop(); } } return res; } int JackAlsaDriver::Stop() { int res = alsa_driver_stop((alsa_driver_t *)fDriver); if (JackAudioDriver::Stop() < 0) { res = -1; } return res; } int JackAlsaDriver::Read() { /* Taken from alsa_driver_run_cycle */ int wait_status; jack_nframes_t nframes; fDelayedUsecs = 0.f; retry: nframes = alsa_driver_wait((alsa_driver_t *)fDriver, -1, &wait_status, &fDelayedUsecs); if (wait_status < 0) return -1; /* driver failed */ if (nframes == 0) { /* we detected an xrun and restarted: notify * clients about the delay. */ jack_log("ALSA XRun wait_status = %d", wait_status); NotifyXRun(fBeginDateUst, fDelayedUsecs); goto retry; /* recoverable error*/ } if (nframes != fEngineControl->fBufferSize) jack_log("JackAlsaDriver::Read warning fBufferSize = %ld nframes = %ld", fEngineControl->fBufferSize, nframes); // Has to be done before read JackDriver::CycleIncTime(); return alsa_driver_read((alsa_driver_t *)fDriver, fEngineControl->fBufferSize); } int JackAlsaDriver::Write() { return alsa_driver_write((alsa_driver_t *)fDriver, fEngineControl->fBufferSize); } void JackAlsaDriver::ReadInputAux(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nread) { for (int chn = 0; chn < fCaptureChannels; chn++) { if (fGraphManager->GetConnectionsNum(fCapturePortList[chn]) > 0) { jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], orig_nframes); alsa_driver_read_from_channel((alsa_driver_t *)fDriver, chn, buf + nread, contiguous); } } } void JackAlsaDriver::MonitorInputAux() { for (int chn = 0; chn < fCaptureChannels; chn++) { JackPort* port = fGraphManager->GetPort(fCapturePortList[chn]); if (port->MonitoringInput()) { ((alsa_driver_t *)fDriver)->input_monitor_mask |= (1 << chn); } } } void JackAlsaDriver::ClearOutputAux() { for (int chn = 0; chn < fPlaybackChannels; chn++) { jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], fEngineControl->fBufferSize); memset(buf, 0, sizeof (jack_default_audio_sample_t) * fEngineControl->fBufferSize); } } void JackAlsaDriver::SetTimetAux(jack_time_t time) { fBeginDateUst = time; } void JackAlsaDriver::WriteOutputAux(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten) { for (int chn = 0; chn < fPlaybackChannels; chn++) { // Output ports if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chn]) > 0) { jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], orig_nframes); alsa_driver_write_to_channel(((alsa_driver_t *)fDriver), chn, buf + nwritten, contiguous); // Monitor ports if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[chn]) > 0) { jack_default_audio_sample_t* monbuf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[chn], orig_nframes); memcpy(monbuf + nwritten, buf + nwritten, contiguous * sizeof(jack_default_audio_sample_t)); } } } } int JackAlsaDriver::is_realtime() const { return fEngineControl->fRealTime; } int JackAlsaDriver::create_thread(pthread_t *thread, int priority, int realtime, void *(*start_routine)(void*), void *arg) { #ifdef __ANDROID__ return JackAndroidThread::StartImp(thread, priority, realtime, start_routine, arg); #else return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg); #endif } jack_port_id_t JackAlsaDriver::port_register(const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size) { jack_port_id_t port_index; int res = fEngine->PortRegister(fClientControl.fRefNum, port_name, port_type, flags, buffer_size, &port_index); return (res == 0) ? port_index : 0; } int JackAlsaDriver::port_unregister(jack_port_id_t port_index) { return fEngine->PortUnRegister(fClientControl.fRefNum, port_index); } void* JackAlsaDriver::port_get_buffer(int port, jack_nframes_t nframes) { return fGraphManager->GetBuffer(port, nframes); } int JackAlsaDriver::port_set_alias(int port, const char* name) { return fGraphManager->GetPort(port)->SetAlias(name); } jack_nframes_t JackAlsaDriver::get_sample_rate() const { return fEngineControl->fSampleRate; } jack_nframes_t JackAlsaDriver::frame_time() const { JackTimer timer; fEngineControl->ReadFrameTime(&timer); return timer.Time2Frames(GetMicroSeconds(), fEngineControl->fBufferSize); } jack_nframes_t JackAlsaDriver::last_frame_time() const { JackTimer timer; fEngineControl->ReadFrameTime(&timer); return timer.CurFrame(); } } // end of namespace #ifdef __cplusplus extern "C" { #endif static jack_driver_param_constraint_desc_t * enum_alsa_devices() { snd_ctl_t * handle; snd_ctl_card_info_t * info; snd_pcm_info_t * pcminfo_capture; snd_pcm_info_t * pcminfo_playback; int card_no = -1; jack_driver_param_value_t card_id; jack_driver_param_value_t device_id; char description[64]; int device_no; bool has_capture; bool has_playback; jack_driver_param_constraint_desc_t * constraint_ptr; uint32_t array_size = 0; snd_ctl_card_info_alloca(&info); snd_pcm_info_alloca(&pcminfo_capture); snd_pcm_info_alloca(&pcminfo_playback); constraint_ptr = NULL; while(snd_card_next(&card_no) >= 0 && card_no >= 0) { snprintf(card_id.str, sizeof(card_id.str), "hw:%d", card_no); if (snd_ctl_open(&handle, card_id.str, 0) >= 0 && snd_ctl_card_info(handle, info) >= 0) { snprintf(card_id.str, sizeof(card_id.str), "hw:%s", snd_ctl_card_info_get_id(info)); if (!jack_constraint_add_enum( &constraint_ptr, &array_size, &card_id, snd_ctl_card_info_get_name(info))) goto fail; device_no = -1; while (snd_ctl_pcm_next_device(handle, &device_no) >= 0 && device_no != -1) { snprintf(device_id.str, sizeof(device_id.str), "%s,%d", card_id.str, device_no); snd_pcm_info_set_device(pcminfo_capture, device_no); snd_pcm_info_set_subdevice(pcminfo_capture, 0); snd_pcm_info_set_stream(pcminfo_capture, SND_PCM_STREAM_CAPTURE); has_capture = snd_ctl_pcm_info(handle, pcminfo_capture) >= 0; snd_pcm_info_set_device(pcminfo_playback, device_no); snd_pcm_info_set_subdevice(pcminfo_playback, 0); snd_pcm_info_set_stream(pcminfo_playback, SND_PCM_STREAM_PLAYBACK); has_playback = snd_ctl_pcm_info(handle, pcminfo_playback) >= 0; if (has_capture && has_playback) { snprintf(description, sizeof(description),"%s (duplex)", snd_pcm_info_get_name(pcminfo_capture)); } else if (has_capture) { snprintf(description, sizeof(description),"%s (capture)", snd_pcm_info_get_name(pcminfo_capture)); } else if (has_playback) { snprintf(description, sizeof(description),"%s (playback)", snd_pcm_info_get_name(pcminfo_playback)); } else { continue; } if (!jack_constraint_add_enum( &constraint_ptr, &array_size, &device_id, description)) goto fail; } snd_ctl_close(handle); } } return constraint_ptr; fail: jack_constraint_free(constraint_ptr); return NULL; } static int dither_opt (char c, DitherAlgorithm* dither) { switch (c) { case '-': case 'n': *dither = None; break; case 'r': *dither = Rectangular; break; case 's': *dither = Shaped; break; case 't': *dither = Triangular; break; default: fprintf (stderr, "ALSA driver: illegal dithering mode %c\n", c); return -1; } return 0; } SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("alsa", JackDriverMaster, "Linux ALSA API based audio backend", &filler); strcpy(value.str, "hw:0"); #ifdef __ANDROID__ jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "ALSA device name", NULL); #else jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, enum_alsa_devices(), "ALSA device name", NULL); #endif strcpy(value.str, "none"); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set device", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Provide playback ports. Optionally set device", NULL); value.ui = 48000U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = 1024U; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = 2U; jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods of playback latency", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "hwmon", 'H', JackDriverParamBool, &value, NULL, "Hardware monitoring, if available", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "hwmeter", 'M', JackDriverParamBool, &value, NULL, "Hardware metering, if available", NULL); value.i = 1; jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "softmode", 's', JackDriverParamBool, &value, NULL, "Soft-mode, no xrun handling", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "monitor", 'm', JackDriverParamBool, &value, NULL, "Provide monitor ports for the output", NULL); value.c = 'n'; jack_driver_descriptor_add_parameter( desc, &filler, "dither", 'z', JackDriverParamChar, &value, jack_constraint_compose_enum_char( JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE, dither_constraint_descr_array), "Dithering mode", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Number of capture channels (defaults to hardware max)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Number of playback channels (defaults to hardware max)", NULL); value.i = FALSE; jack_driver_descriptor_add_parameter(desc, &filler, "shorts", 'S', JackDriverParamBool, &value, NULL, "Try 16-bit samples before 32-bit", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency (frames)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency (frames)", NULL); strcpy(value.str, "none"); jack_driver_descriptor_add_parameter( desc, &filler, "midi-driver", 'X', JackDriverParamString, &value, jack_constraint_compose_enum_str( JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE, midi_constraint_descr_array), "ALSA MIDI driver", NULL); return desc; } static Jack::JackAlsaDriver* g_alsa_driver; SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t srate = 48000; jack_nframes_t frames_per_interrupt = 1024; unsigned long user_nperiods = 2; const char *playback_pcm_name = "hw:0"; const char *capture_pcm_name = "hw:0"; int hw_monitoring = FALSE; int hw_metering = FALSE; int capture = FALSE; int playback = FALSE; int soft_mode = FALSE; int monitor = FALSE; DitherAlgorithm dither = None; int user_capture_nchnls = 0; int user_playback_nchnls = 0; int shorts_first = FALSE; jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; const JSList * node; const jack_driver_param_t * param; const char *midi_driver = "none"; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'C': capture = TRUE; if (strcmp (param->value.str, "none") != 0) { capture_pcm_name = strdup (param->value.str); jack_log("capture device %s", capture_pcm_name); } break; case 'P': playback = TRUE; if (strcmp (param->value.str, "none") != 0) { playback_pcm_name = strdup (param->value.str); jack_log("playback device %s", playback_pcm_name); } break; case 'D': playback = TRUE; capture = TRUE; break; case 'd': if (strcmp (param->value.str, "none") != 0) { playback_pcm_name = strdup (param->value.str); capture_pcm_name = strdup (param->value.str); jack_log("playback device %s", playback_pcm_name); jack_log("capture device %s", capture_pcm_name); } break; case 'H': hw_monitoring = param->value.i; break; case 'm': monitor = param->value.i; break; case 'M': hw_metering = param->value.i; break; case 'r': srate = param->value.ui; jack_log("apparent rate = %d", srate); break; case 'p': frames_per_interrupt = param->value.ui; jack_log("frames per period = %d", frames_per_interrupt); break; case 'n': user_nperiods = param->value.ui; if (user_nperiods < 2) { /* enforce minimum value */ user_nperiods = 2; } break; case 's': soft_mode = param->value.i; break; case 'z': if (dither_opt (param->value.c, &dither)) { return NULL; } break; case 'i': user_capture_nchnls = param->value.ui; break; case 'o': user_playback_nchnls = param->value.ui; break; case 'S': shorts_first = param->value.i; break; case 'I': systemic_input_latency = param->value.ui; break; case 'O': systemic_output_latency = param->value.ui; break; case 'X': midi_driver = strdup(param->value.str); break; } } /* duplex is the default */ if (!capture && !playback) { capture = TRUE; playback = TRUE; } g_alsa_driver = new Jack::JackAlsaDriver("system", "alsa_pcm", engine, table); Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(g_alsa_driver); // Special open for ALSA driver... if (g_alsa_driver->Open(frames_per_interrupt, user_nperiods, srate, hw_monitoring, hw_metering, capture, playback, dither, soft_mode, monitor, user_capture_nchnls, user_playback_nchnls, shorts_first, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, midi_driver) == 0) { return threaded_driver; } else { delete threaded_driver; // Delete the decorated driver return NULL; } } // Code to be used in alsa_driver.c void ReadInput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nread) { g_alsa_driver->ReadInputAux(orig_nframes, contiguous, nread); } void MonitorInput() { g_alsa_driver->MonitorInputAux(); } void ClearOutput() { g_alsa_driver->ClearOutputAux(); } void WriteOutput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten) { g_alsa_driver->WriteOutputAux(orig_nframes, contiguous, nwritten); } void SetTime(jack_time_t time) { g_alsa_driver->SetTimetAux(time); } int Restart() { int res; if ((res = g_alsa_driver->Stop()) == 0) { res = g_alsa_driver->Start(); } return res; } #ifdef __cplusplus } #endif 1.9.12~dfsg/linux/alsa/alsa_midi_jackmp.cpp0000644000000000000000000000526613214314510017403 0ustar rootroot/* * Copyright (c) 2006,2007 Dmitry S. Baikov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "JackAlsaDriver.h" #include "JackPort.h" #include "alsa_midi_impl.h" using Jack::JackAlsaDriver; struct fake_port_t { JackAlsaDriver* driver; int port_id; fake_port_t(JackAlsaDriver *d, int i) : driver(d), port_id(i) {} }; int JACK_is_realtime(jack_client_t* client) { return ((JackAlsaDriver*)client)->is_realtime(); } int JACK_client_create_thread(jack_client_t* client, pthread_t *thread, int priority, int realtime, void *(*start_routine)(void*), void *arg) { return ((JackAlsaDriver*)client)->create_thread(thread, priority, realtime, start_routine, arg); } jack_port_t* JACK_port_register(jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size) { JackAlsaDriver *driver = (JackAlsaDriver*)client; int port_id = driver->port_register(port_name, port_type, flags, buffer_size); if (port_id == NO_PORT) { return 0; } else { return (jack_port_t*) new fake_port_t(driver, port_id); } } int JACK_port_unregister(jack_client_t *client, jack_port_t *port) { fake_port_t* real = (fake_port_t*)port; int res = real->driver->port_unregister(real->port_id); delete real; return res; } void* JACK_port_get_buffer(jack_port_t *port, jack_nframes_t nframes) { fake_port_t* real = (fake_port_t*)port; return real->driver->port_get_buffer(real->port_id, nframes); } int JACK_port_set_alias(jack_port_t *port, const char* name) { fake_port_t* real = (fake_port_t*)port; return real->driver->port_set_alias(real->port_id, name); } jack_nframes_t JACK_get_sample_rate(jack_client_t *client) { return ((JackAlsaDriver*)client)->get_sample_rate(); } jack_nframes_t JACK_frame_time(jack_client_t *client) { return ((JackAlsaDriver*)client)->frame_time(); } jack_nframes_t JACK_last_frame_time(jack_client_t *client) { return ((JackAlsaDriver*)client)->last_frame_time(); } 1.9.12~dfsg/linux/alsa/hdsp.h0000644000000000000000000000207613214314510014533 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: hdsp.h,v 1.3 2005/11/23 11:24:29 letz Exp $ */ #ifndef __jack_hdsp_h__ #define __jack_hdsp_h__ #include typedef struct { alsa_driver_t *driver; } hdsp_t; #ifdef __cplusplus extern "C" { #endif jack_hardware_t * jack_alsa_hdsp_hw_new (alsa_driver_t *driver); #ifdef __cplusplus } #endif #endif /* __jack_hdsp_h__*/ 1.9.12~dfsg/linux/alsa/hardware.h0000644000000000000000000000422013214314510015363 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: hardware.h,v 1.3 2005/11/23 11:24:29 letz Exp $ */ #ifndef __jack_hardware_h__ #define __jack_hardware_h__ #include "types.h" typedef enum { AutoSync, WordClock, ClockMaster } SampleClockMode; typedef enum { Cap_HardwareMonitoring = 0x1, Cap_AutoSync = 0x2, Cap_WordClock = 0x4, Cap_ClockMaster = 0x8, Cap_ClockLockReporting = 0x10, Cap_HardwareMetering = 0x20 } Capabilities; struct _jack_hardware; typedef void (*JackHardwareReleaseFunction)(struct _jack_hardware *); typedef int (*JackHardwareSetInputMonitorMaskFunction)(struct _jack_hardware *, unsigned long); typedef int (*JackHardwareChangeSampleClockFunction)(struct _jack_hardware *, SampleClockMode); typedef double (*JackHardwareGetHardwarePeak)(jack_port_t *port, jack_nframes_t frames); typedef double (*JackHardwareGetHardwarePower)(jack_port_t *port, jack_nframes_t frames); typedef struct _jack_hardware { unsigned long capabilities; unsigned long input_monitor_mask; JackHardwareChangeSampleClockFunction change_sample_clock; JackHardwareSetInputMonitorMaskFunction set_input_monitor_mask; JackHardwareReleaseFunction release; JackHardwareGetHardwarePeak get_hardware_peak; JackHardwareGetHardwarePower get_hardware_power; void *private_hw; } jack_hardware_t; #ifdef __cplusplus extern "C" { #endif jack_hardware_t * jack_hardware_new (); #ifdef __cplusplus } #endif #endif /* __jack_hardware_h__ */ 1.9.12~dfsg/linux/alsa/hammerfall.h0000644000000000000000000000236113214314510015702 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: hammerfall.h,v 1.3 2005/11/23 11:24:29 letz Exp $ */ #ifndef __jack_hammerfall_h__ #define __jack_hammerfall_h__ #include typedef struct { int lock_status[3]; int sync_status[3]; int said_that_spdif_is_fine; pthread_t monitor_thread; alsa_driver_t *driver; struct timespec monitor_interval; } hammerfall_t; #ifdef __cplusplus extern "C" { #endif jack_hardware_t *jack_alsa_hammerfall_hw_new (alsa_driver_t *driver); #ifdef __cplusplus } #endif #endif /* __jack_hammerfall_h__*/ 1.9.12~dfsg/linux/alsa/JackAlsaAdapter.h0000644000000000000000000006460113214314510016551 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackAlsaAdapter__ #define __JackAlsaAdapter__ #include #include #include #include #include "JackAudioAdapterInterface.h" #include "JackPlatformPlug.h" #include "JackError.h" #include "jack.h" #include "jslist.h" namespace Jack { inline void* aligned_calloc ( size_t nmemb, size_t size ) { return ( void* ) calloc ( nmemb, size ); } #define max(x,y) (((x)>(y)) ? (x) : (y)) #define min(x,y) (((x)<(y)) ? (x) : (y)) #define check_error(err) if (err) { jack_error("%s:%d, alsa error %d : %s", __FILE__, __LINE__, err, snd_strerror(err)); return err; } #define check_error_msg(err,msg) if (err) { jack_error("%s:%d, %s : %s(%d)", __FILE__, __LINE__, msg, snd_strerror(err), err); return err; } #define display_error_msg(err,msg) if (err) { jack_error("%s:%d, %s : %s(%d)", __FILE__, __LINE__, msg, snd_strerror(err), err); } /** * A convenient class to pass parameters to AudioInterface */ class AudioParam { public: const char* fCardName; unsigned int fFrequency; int fBuffering; unsigned int fSoftInputs; unsigned int fSoftOutputs; public: AudioParam() : fCardName ( "hw:0" ), fFrequency ( 44100 ), fBuffering ( 512 ), fSoftInputs ( 2 ), fSoftOutputs ( 2 ) {} AudioParam ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) : fCardName ( "hw:0" ), fFrequency ( sample_rate ), fBuffering ( buffer_size ), fSoftInputs ( 2 ), fSoftOutputs ( 2 ) {} AudioParam& cardName ( const char* n ) { fCardName = n; return *this; } AudioParam& frequency ( int f ) { fFrequency = f; return *this; } AudioParam& buffering ( int fpb ) { fBuffering = fpb; return *this; } void setInputs ( int inputs ) { fSoftInputs = inputs; } AudioParam& inputs ( int n ) { fSoftInputs = n; return *this; } void setOutputs ( int outputs ) { fSoftOutputs = outputs; } AudioParam& outputs ( int n ) { fSoftOutputs = n; return *this; } }; /** * An ALSA audio interface */ class AudioInterface : public AudioParam { public: //device info snd_pcm_t* fOutputDevice; snd_pcm_t* fInputDevice; snd_pcm_hw_params_t* fInputParams; snd_pcm_hw_params_t* fOutputParams; //samples info snd_pcm_format_t fSampleFormat; snd_pcm_access_t fSampleAccess; //channels const char* fCaptureName; const char* fPlaybackName; unsigned int fCardInputs; unsigned int fCardOutputs; //stream parameters unsigned int fPeriod; //interleaved mode audiocard buffers void* fInputCardBuffer; void* fOutputCardBuffer; //non-interleaved mode audiocard buffers void* fInputCardChannels[256]; void* fOutputCardChannels[256]; //non-interleaved mod, floating point software buffers jack_default_audio_sample_t* fInputSoftChannels[256]; jack_default_audio_sample_t* fOutputSoftChannels[256]; //public methods --------------------------------------------------------- const char* cardName() { return fCardName; } int frequency() { return fFrequency; } int buffering() { return fBuffering; } jack_default_audio_sample_t** inputSoftChannels() { return fInputSoftChannels; } jack_default_audio_sample_t** outputSoftChannels() { return fOutputSoftChannels; } AudioInterface ( const AudioParam& ap = AudioParam() ) : AudioParam ( ap ) { fInputDevice = 0; fOutputDevice = 0; fInputParams = 0; fOutputParams = 0; fPeriod = 2; fCaptureName = NULL; fPlaybackName = NULL; fInputCardBuffer = 0; fOutputCardBuffer = 0; for ( int i = 0; i < 256; i++ ) { fInputCardChannels[i] = 0; fOutputCardChannels[i] = 0; fInputSoftChannels[i] = 0; fOutputSoftChannels[i] = 0; } } AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) : AudioParam ( buffer_size, sample_rate ) { fInputCardBuffer = 0; fOutputCardBuffer = 0; fCaptureName = NULL; fPlaybackName = NULL; for ( int i = 0; i < 256; i++ ) { fInputCardChannels[i] = 0; fOutputCardChannels[i] = 0; fInputSoftChannels[i] = 0; fOutputSoftChannels[i] = 0; } } /** * Open the audio interface */ int open() { //open input/output streams check_error ( snd_pcm_open ( &fInputDevice, (fCaptureName == NULL) ? fCardName : fCaptureName, SND_PCM_STREAM_CAPTURE, 0 ) ); check_error ( snd_pcm_open ( &fOutputDevice, (fPlaybackName == NULL) ? fCardName : fPlaybackName, SND_PCM_STREAM_PLAYBACK, 0 ) ); //get hardware input parameters check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) ); setAudioParams ( fInputDevice, fInputParams ); //get hardware output parameters check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) ) setAudioParams ( fOutputDevice, fOutputParams ); // set the number of physical input and output channels close to what we need fCardInputs = fSoftInputs; fCardOutputs = fSoftOutputs; snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs); snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs); //set input/output param check_error ( snd_pcm_hw_params ( fInputDevice, fInputParams ) ); check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) ); //set hardware buffers if ( fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED ) { fInputCardBuffer = aligned_calloc ( interleavedBufferSize ( fInputParams ), 1 ); fOutputCardBuffer = aligned_calloc ( interleavedBufferSize ( fOutputParams ), 1 ); } else { for ( unsigned int i = 0; i < fCardInputs; i++ ) fInputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fInputParams ), 1 ); for ( unsigned int i = 0; i < fCardOutputs; i++ ) fOutputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fOutputParams ), 1 ); } //set floating point buffers needed by the dsp code fSoftInputs = max ( fSoftInputs, fCardInputs ); assert ( fSoftInputs < 256 ); fSoftOutputs = max ( fSoftOutputs, fCardOutputs ); assert ( fSoftOutputs < 256 ); for ( unsigned int i = 0; i < fSoftInputs; i++ ) { fInputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) ); for ( int j = 0; j < fBuffering; j++ ) fInputSoftChannels[i][j] = 0.0; } for ( unsigned int i = 0; i < fSoftOutputs; i++ ) { fOutputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) ); for ( int j = 0; j < fBuffering; j++ ) fOutputSoftChannels[i][j] = 0.0; } return 0; } int close() { snd_pcm_hw_params_free ( fInputParams ); snd_pcm_hw_params_free ( fOutputParams ); snd_pcm_close ( fInputDevice ); snd_pcm_close ( fOutputDevice ); for ( unsigned int i = 0; i < fSoftInputs; i++ ) if ( fInputSoftChannels[i] ) free ( fInputSoftChannels[i] ); for ( unsigned int i = 0; i < fSoftOutputs; i++ ) if ( fOutputSoftChannels[i] ) free ( fOutputSoftChannels[i] ); for ( unsigned int i = 0; i < fCardInputs; i++ ) if ( fInputCardChannels[i] ) free ( fInputCardChannels[i] ); for ( unsigned int i = 0; i < fCardOutputs; i++ ) if ( fOutputCardChannels[i] ) free ( fOutputCardChannels[i] ); if ( fInputCardBuffer ) free ( fInputCardBuffer ); if ( fOutputCardBuffer ) free ( fOutputCardBuffer ); return 0; } int setAudioParams ( snd_pcm_t* stream, snd_pcm_hw_params_t* params ) { //set params record with initial values check_error_msg ( snd_pcm_hw_params_any ( stream, params ), "unable to init parameters" ) //set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved if ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ) ) check_error_msg ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ), "unable to set access mode neither to non-interleaved or to interleaved" ); snd_pcm_hw_params_get_access ( params, &fSampleAccess ); //search for 32-bits or 16-bits format if ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S32 ) ) check_error_msg ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S16 ), "unable to set format to either 32-bits or 16-bits" ); snd_pcm_hw_params_get_format ( params, &fSampleFormat ); //set sample frequency snd_pcm_hw_params_set_rate_near ( stream, params, &fFrequency, 0 ); //set period and period size (buffering) check_error_msg ( snd_pcm_hw_params_set_period_size ( stream, params, fBuffering, 0 ), "period size not available" ); check_error_msg ( snd_pcm_hw_params_set_periods ( stream, params, fPeriod, 0 ), "number of periods not available" ); return 0; } ssize_t interleavedBufferSize ( snd_pcm_hw_params_t* params ) { _snd_pcm_format format; unsigned int channels; snd_pcm_hw_params_get_format ( params, &format ); snd_pcm_uframes_t psize; snd_pcm_hw_params_get_period_size ( params, &psize, NULL ); snd_pcm_hw_params_get_channels ( params, &channels ); ssize_t bsize = snd_pcm_format_size ( format, psize * channels ); return bsize; } ssize_t noninterleavedBufferSize ( snd_pcm_hw_params_t* params ) { _snd_pcm_format format; snd_pcm_hw_params_get_format ( params, &format ); snd_pcm_uframes_t psize; snd_pcm_hw_params_get_period_size ( params, &psize, NULL ); ssize_t bsize = snd_pcm_format_size ( format, psize ); return bsize; } /** * Read audio samples from the audio card. Convert samples to floats and take * care of interleaved buffers */ int read() { int count, s; unsigned int c; switch ( fSampleAccess ) { case SND_PCM_ACCESS_RW_INTERLEAVED : count = snd_pcm_readi ( fInputDevice, fInputCardBuffer, fBuffering ); if ( count < 0 ) { display_error_msg ( count, "reading samples" ); check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" ); } if ( fSampleFormat == SND_PCM_FORMAT_S16 ) { short* buffer16b = ( short* ) fInputCardBuffer; for ( s = 0; s < fBuffering; s++ ) for ( c = 0; c < fCardInputs; c++ ) fInputSoftChannels[c][s] = jack_default_audio_sample_t(buffer16b[c + s*fCardInputs]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX)); } else // SND_PCM_FORMAT_S32 { int32_t* buffer32b = ( int32_t* ) fInputCardBuffer; for ( s = 0; s < fBuffering; s++ ) for ( c = 0; c < fCardInputs; c++ ) fInputSoftChannels[c][s] = jack_default_audio_sample_t(buffer32b[c + s*fCardInputs]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX)); } break; case SND_PCM_ACCESS_RW_NONINTERLEAVED : count = snd_pcm_readn ( fInputDevice, fInputCardChannels, fBuffering ); if ( count < 0 ) { display_error_msg ( count, "reading samples" ); check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" ); } if ( fSampleFormat == SND_PCM_FORMAT_S16 ) { short* chan16b; for ( c = 0; c < fCardInputs; c++ ) { chan16b = ( short* ) fInputCardChannels[c]; for ( s = 0; s < fBuffering; s++ ) fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan16b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX)); } } else // SND_PCM_FORMAT_S32 { int32_t* chan32b; for ( c = 0; c < fCardInputs; c++ ) { chan32b = ( int32_t* ) fInputCardChannels[c]; for ( s = 0; s < fBuffering; s++ ) fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan32b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX)); } } break; default : check_error_msg ( -10000, "unknow access mode" ); break; } return 0; } /** * write the output soft channels to the audio card. Convert sample * format and interleaves buffers when needed */ int write() { int count, f; unsigned int c; recovery: switch ( fSampleAccess ) { case SND_PCM_ACCESS_RW_INTERLEAVED : if ( fSampleFormat == SND_PCM_FORMAT_S16 ) { short* buffer16b = ( short* ) fOutputCardBuffer; for ( f = 0; f < fBuffering; f++ ) { for ( unsigned int c = 0; c < fCardOutputs; c++ ) { jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; buffer16b[c + f * fCardOutputs] = short(max(min (x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(SHRT_MAX)); } } } else // SND_PCM_FORMAT_S32 { int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer; for ( f = 0; f < fBuffering; f++ ) { for ( unsigned int c = 0; c < fCardOutputs; c++ ) { jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; buffer32b[c + f * fCardOutputs] = int32_t(max(min(x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(INT_MAX)); } } } count = snd_pcm_writei ( fOutputDevice, fOutputCardBuffer, fBuffering ); if ( count < 0 ) { display_error_msg ( count, "w3" ); int err = snd_pcm_prepare ( fOutputDevice ); check_error_msg ( err, "preparing output stream" ); goto recovery; } break; case SND_PCM_ACCESS_RW_NONINTERLEAVED : if ( fSampleFormat == SND_PCM_FORMAT_S16 ) { for ( c = 0; c < fCardOutputs; c++ ) { short* chan16b = ( short* ) fOutputCardChannels[c]; for ( f = 0; f < fBuffering; f++ ) { jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; chan16b[f] = short(max(min (x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(SHRT_MAX)); } } } else { for ( c = 0; c < fCardOutputs; c++ ) { int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c]; for ( f = 0; f < fBuffering; f++ ) { jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; chan32b[f] = int32_t(max(min(x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(INT_MAX)); } } } count = snd_pcm_writen ( fOutputDevice, fOutputCardChannels, fBuffering ); if ( count<0 ) { display_error_msg ( count, "w3" ); int err = snd_pcm_prepare ( fOutputDevice ); check_error_msg ( err, "preparing output stream" ); goto recovery; } break; default : check_error_msg ( -10000, "unknow access mode" ); break; } return 0; } /** * print short information on the audio device */ int shortinfo() { int err; snd_ctl_card_info_t* card_info; snd_ctl_t* ctl_handle; err = snd_ctl_open ( &ctl_handle, fCardName, 0 ); check_error ( err ); snd_ctl_card_info_alloca ( &card_info ); err = snd_ctl_card_info ( ctl_handle, card_info ); check_error ( err ); jack_info ( "%s|%d|%d|%d|%d|%s", snd_ctl_card_info_get_driver ( card_info ), fCardInputs, fCardOutputs, fFrequency, fBuffering, snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ) ); snd_ctl_close(ctl_handle); } /** * print more detailled information on the audio device */ int longinfo() { snd_ctl_card_info_t* card_info; snd_ctl_t* ctl_handle; //display info jack_info ( "Audio Interface Description :" ); jack_info ( "Sampling Frequency : %d, Sample Format : %s, buffering : %d, nperiod : %d", fFrequency, snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ), fBuffering, fPeriod ); jack_info ( "Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs ); jack_info ( "Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs ); //get audio card info and display check_error ( snd_ctl_open ( &ctl_handle, fCardName, 0 ) ); snd_ctl_card_info_alloca ( &card_info ); check_error ( snd_ctl_card_info ( ctl_handle, card_info ) ); printCardInfo ( card_info ); //display input/output streams info if ( fSoftInputs > 0 ) printHWParams ( fInputParams ); if ( fSoftOutputs > 0 ) printHWParams ( fOutputParams ); snd_ctl_close(ctl_handle); return 0; } void printCardInfo ( snd_ctl_card_info_t* ci ) { jack_info ( "Card info (address : %p)", ci ); jack_info ( "\tID = %s", snd_ctl_card_info_get_id ( ci ) ); jack_info ( "\tDriver = %s", snd_ctl_card_info_get_driver ( ci ) ); jack_info ( "\tName = %s", snd_ctl_card_info_get_name ( ci ) ); jack_info ( "\tLongName = %s", snd_ctl_card_info_get_longname ( ci ) ); jack_info ( "\tMixerName = %s", snd_ctl_card_info_get_mixername ( ci ) ); jack_info ( "\tComponents = %s", snd_ctl_card_info_get_components ( ci ) ); jack_info ( "--------------" ); } void printHWParams ( snd_pcm_hw_params_t* params ) { jack_info ( "HW Params info (address : %p)\n", params ); #if 0 jack_info ( "\tChannels = %d", snd_pcm_hw_params_get_channels ( params, NULL ) ); jack_info ( "\tFormat = %s", snd_pcm_format_name ( ( _snd_pcm_format ) snd_pcm_hw_params_get_format ( params, NULL ) ) ); jack_info ( "\tAccess = %s", snd_pcm_access_name ( ( _snd_pcm_access ) snd_pcm_hw_params_get_access ( params, NULL ) ) ); jack_info ( "\tRate = %d", snd_pcm_hw_params_get_rate ( params, NULL, NULL ) ); jack_info ( "\tPeriods = %d", snd_pcm_hw_params_get_periods ( params, NULL, NULL ) ); jack_info ( "\tPeriod size = %d", ( int ) snd_pcm_hw_params_get_period_size ( params, NULL, NULL ) ); jack_info ( "\tPeriod time = %d", snd_pcm_hw_params_get_period_time ( params, NULL, NULL ) ); jack_info ( "\tBuffer size = %d", ( int ) snd_pcm_hw_params_get_buffer_size ( params, NULL ) ); jack_info ( "\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time ( params, NULL, NULL ) ); #endif jack_info ( "--------------" ); } }; /*! \brief Audio adapter using ALSA API. */ class JackAlsaAdapter : public JackAudioAdapterInterface, public JackRunnableInterface { private: JackThread fThread; AudioInterface fAudioInterface; public: JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ); ~JackAlsaAdapter() {} virtual int Open(); virtual int Close(); virtual int SetSampleRate ( jack_nframes_t sample_rate ); virtual int SetBufferSize ( jack_nframes_t buffer_size ); virtual bool Init(); virtual bool Execute(); }; } #ifdef __cplusplus extern "C" { #endif #include "JackCompilerDeps.h" #include "driver_interface.h" SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor(); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/linux/alsa/hammerfall.c0000644000000000000000000001735713214314510015710 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: hammerfall.c,v 1.3 2005/09/29 14:51:59 letz Exp $ */ #include "hardware.h" #include "alsa_driver.h" #include "hammerfall.h" #include "JackError.h" #define FALSE 0 #define TRUE 1 /* Set this to 1 if you want this compile error: * warning: `hammerfall_monitor_controls' defined but not used */ #define HAMMERFALL_MONITOR_CONTROLS 0 static void set_control_id (snd_ctl_elem_id_t *ctl, const char *name) { snd_ctl_elem_id_set_name (ctl, name); snd_ctl_elem_id_set_numid (ctl, 0); snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_id_set_device (ctl, 0); snd_ctl_elem_id_set_subdevice (ctl, 0); snd_ctl_elem_id_set_index (ctl, 0); } #if HAMMERFALL_MONITOR_CONTROLS static void hammerfall_broadcast_channel_status_change (hammerfall_t *h, int lock, int sync, channel_t lowchn, channel_t highchn) { channel_t chn; ClockSyncStatus status = 0; if (lock) { status |= Lock; } else { status |= NoLock; } if (sync) { status |= Sync; } else { status |= NoSync; } for (chn = lowchn; chn < highchn; chn++) { alsa_driver_set_clock_sync_status (h->driver, chn, status); } } static void hammerfall_check_sync_state (hammerfall_t *h, int val, int adat_id) { int lock; int sync; /* S/PDIF channel is always locked and synced, but we only need tell people once that this is TRUE. XXX - maybe need to make sure that the rate matches our idea of the current rate ? */ if (!h->said_that_spdif_is_fine) { ClockSyncStatus status; status = Lock|Sync; /* XXX broken! fix for hammerfall light ! */ alsa_driver_set_clock_sync_status (h->driver, 24, status); alsa_driver_set_clock_sync_status (h->driver, 25, status); h->said_that_spdif_is_fine = TRUE; } lock = (val & 0x1) ? TRUE : FALSE; sync = (val & 0x2) ? TRUE : FALSE; if (h->lock_status[adat_id] != lock || h->sync_status[adat_id] != sync) { hammerfall_broadcast_channel_status_change (h, lock, sync, adat_id*8, (adat_id*8)+8); } h->lock_status[adat_id] = lock; h->sync_status[adat_id] = sync; } static void hammerfall_check_sync (hammerfall_t *h, snd_ctl_elem_value_t *ctl) { const char *name; int val; snd_ctl_elem_id_t *ctl_id; jack_info ("check sync"); snd_ctl_elem_id_alloca (&ctl_id); snd_ctl_elem_value_get_id (ctl, ctl_id); name = snd_ctl_elem_id_get_name (ctl_id); if (strcmp (name, "ADAT1 Sync Check") == 0) { val = snd_ctl_elem_value_get_enumerated (ctl, 0); hammerfall_check_sync_state (h, val, 0); } else if (strcmp (name, "ADAT2 Sync Check") == 0) { val = snd_ctl_elem_value_get_enumerated (ctl, 0); hammerfall_check_sync_state (h, val, 1); } else if (strcmp (name, "ADAT3 Sync Check") == 0) { val = snd_ctl_elem_value_get_enumerated (ctl, 0); hammerfall_check_sync_state (h, val, 2); } else { jack_error ("Hammerfall: unknown control \"%s\"", name); } } #endif /* HAMMERFALL_MONITOR_CONTROLS */ static int hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) { hammerfall_t *h = (hammerfall_t *) hw->private_hw; snd_ctl_elem_value_t *ctl; snd_ctl_elem_id_t *ctl_id; int err; int i; snd_ctl_elem_value_alloca (&ctl); snd_ctl_elem_id_alloca (&ctl_id); set_control_id (ctl_id, "Channels Thru"); snd_ctl_elem_value_set_id (ctl, ctl_id); for (i = 0; i < 26; i++) { snd_ctl_elem_value_set_integer (ctl, i, (mask & (1<driver->ctl_handle, ctl)) != 0) { jack_error ("ALSA/Hammerfall: cannot set input monitoring (%s)", snd_strerror (err)); return -1; } hw->input_monitor_mask = mask; return 0; } static int hammerfall_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) { hammerfall_t *h = (hammerfall_t *) hw->private_hw; snd_ctl_elem_value_t *ctl; snd_ctl_elem_id_t *ctl_id; int err; snd_ctl_elem_value_alloca (&ctl); snd_ctl_elem_id_alloca (&ctl_id); set_control_id (ctl_id, "Sync Mode"); snd_ctl_elem_value_set_id (ctl, ctl_id); switch (mode) { case AutoSync: snd_ctl_elem_value_set_enumerated (ctl, 0, 0); break; case ClockMaster: snd_ctl_elem_value_set_enumerated (ctl, 0, 1); break; case WordClock: snd_ctl_elem_value_set_enumerated (ctl, 0, 2); break; } if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) < 0) { jack_error ("ALSA-Hammerfall: cannot set clock mode"); } return 0; } static void hammerfall_release (jack_hardware_t *hw) { hammerfall_t *h = (hammerfall_t *) hw->private_hw; void *status; if (h == 0) { return; } #ifndef __ANDROID__ if (h->monitor_thread) { pthread_cancel (h->monitor_thread); pthread_join (h->monitor_thread, &status); } #endif free (h); } #if HAMMERFALL_MONITOR_CONTROLS static void * hammerfall_monitor_controls (void *arg) { jack_hardware_t *hw = (jack_hardware_t *) arg; hammerfall_t *h = (hammerfall_t *) hw->private_hw; snd_ctl_elem_id_t *switch_id[3]; snd_ctl_elem_value_t *sw[3]; pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); snd_ctl_elem_id_malloc (&switch_id[0]); snd_ctl_elem_id_malloc (&switch_id[1]); snd_ctl_elem_id_malloc (&switch_id[2]); snd_ctl_elem_value_malloc (&sw[0]); snd_ctl_elem_value_malloc (&sw[1]); snd_ctl_elem_value_malloc (&sw[2]); set_control_id (switch_id[0], "ADAT1 Sync Check"); set_control_id (switch_id[1], "ADAT2 Sync Check"); set_control_id (switch_id[2], "ADAT3 Sync Check"); snd_ctl_elem_value_set_id (sw[0], switch_id[0]); snd_ctl_elem_value_set_id (sw[1], switch_id[1]); snd_ctl_elem_value_set_id (sw[2], switch_id[2]); while (1) { if (snd_ctl_elem_read (h->driver->ctl_handle, sw[0])) { jack_error ("cannot read control switch 0 ..."); } hammerfall_check_sync (h, sw[0]); if (snd_ctl_elem_read (h->driver->ctl_handle, sw[1])) { jack_error ("cannot read control switch 0 ..."); } hammerfall_check_sync (h, sw[1]); if (snd_ctl_elem_read (h->driver->ctl_handle, sw[2])) { jack_error ("cannot read control switch 0 ..."); } hammerfall_check_sync (h, sw[2]); if (nanosleep (&h->monitor_interval, 0)) { break; } } pthread_exit (0); } #endif /* HAMMERFALL_MONITOR_CONTROLS */ jack_hardware_t * jack_alsa_hammerfall_hw_new (alsa_driver_t *driver) { jack_hardware_t *hw; hammerfall_t *h; hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting; hw->input_monitor_mask = 0; hw->private_hw = 0; hw->set_input_monitor_mask = hammerfall_set_input_monitor_mask; hw->change_sample_clock = hammerfall_change_sample_clock; hw->release = hammerfall_release; h = (hammerfall_t *) malloc (sizeof (hammerfall_t)); h->lock_status[0] = FALSE; h->sync_status[0] = FALSE; h->lock_status[1] = FALSE; h->sync_status[1] = FALSE; h->lock_status[2] = FALSE; h->sync_status[2] = FALSE; h->said_that_spdif_is_fine = FALSE; h->driver = driver; h->monitor_interval.tv_sec = 1; h->monitor_interval.tv_nsec = 0; hw->private_hw = h; #if 0 if (pthread_create (&h->monitor_thread, 0, hammerfall_monitor_controls, hw)) { jack_error ("ALSA/Hammerfall: cannot create sync monitor thread"); } #endif return hw; } 1.9.12~dfsg/linux/alsa/alsa_rawmidi.c0000644000000000000000000007465213214314510016235 0ustar rootroot/* * ALSA RAWMIDI < - > JACK MIDI bridge * * Copyright (c) 2006,2007 Dmitry S. Baikov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Required for clock_nanosleep(). Thanks, Nedko */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include "ringbuffer.h" #include "midiport.h" #include "alsa_midi_impl.h" #include "midi_pack.h" #include "midi_unpack.h" #include "JackError.h" extern int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem); enum { NANOSLEEP_RESOLUTION = 7000 }; #define NFRAMES_INF ULLONG_MAX enum { #ifndef JACK_MIDI_DEBUG MAX_PFDS = 64, MAX_PORTS = MAX_PFDS-1, MAX_EVENTS = 4096, MAX_DATA = 64*1024, MIDI_THREAD_PRIO = 80 #else MAX_PFDS = 6, MAX_PORTS = MAX_PFDS-1, MAX_EVENTS = 16, MAX_DATA = 64, MIDI_THREAD_PRIO = 80 #endif }; enum PortState { PORT_DESTROYED, PORT_CREATED, PORT_ADDED_TO_JACK, PORT_ADDED_TO_MIDI, PORT_REMOVED_FROM_MIDI, PORT_REMOVED_FROM_JACK, PORT_ZOMBIFIED, }; typedef struct { int id[4]; //card, dev, dir, sub; } alsa_id_t; typedef struct { jack_time_t time; int size; int overruns; } event_head_t; typedef struct midi_port_t midi_port_t; struct midi_port_t { midi_port_t *next; enum PortState state; alsa_id_t id; char dev[16]; char name[64]; jack_port_t *jack; snd_rawmidi_t *rawmidi; int npfds; int is_ready; jack_ringbuffer_t *event_ring; jack_ringbuffer_t *data_ring; }; typedef struct input_port_t { midi_port_t base; // jack midi_unpack_t unpack; // midi int overruns; } input_port_t; typedef struct output_port_t { midi_port_t base; // jack midi_pack_t packer; // midi event_head_t next_event; int todo; } output_port_t; typedef struct alsa_rawmidi_t alsa_rawmidi_t; typedef struct { alsa_rawmidi_t *midi; midi_port_t *port; void *buffer; jack_time_t frame_time; jack_nframes_t nframes; } process_jack_t; typedef struct { alsa_rawmidi_t *midi; int mode; midi_port_t *port; struct pollfd *rpfds; struct pollfd *wpfds; int max_pfds; jack_nframes_t cur_frames; jack_time_t cur_time; jack_time_t next_time; } process_midi_t; typedef struct midi_stream_t { alsa_rawmidi_t *owner; int mode; const char *name; pthread_t thread; int wake_pipe[2]; struct { jack_ringbuffer_t *new_ports; int nports; midi_port_t *ports[MAX_PORTS]; } jack, midi; size_t port_size; int (*port_init)(alsa_rawmidi_t *midi, midi_port_t *port); void (*port_close)(alsa_rawmidi_t *midi, midi_port_t *port); void (*process_jack)(process_jack_t *j); int (*process_midi)(process_midi_t *m); } midi_stream_t; struct alsa_rawmidi_t { alsa_midi_t ops; jack_client_t *client; int keep_walking; struct { pthread_t thread; midi_port_t *ports; int wake_pipe[2]; } scan; midi_stream_t in; midi_stream_t out; int midi_in_cnt; int midi_out_cnt; }; static int input_port_init(alsa_rawmidi_t *midi, midi_port_t *port); static void input_port_close(alsa_rawmidi_t *midi, midi_port_t *port); static void do_jack_input(process_jack_t *j); static int do_midi_input(process_midi_t *m); static int output_port_init(alsa_rawmidi_t *midi, midi_port_t *port); static void output_port_close(alsa_rawmidi_t *midi, midi_port_t *port); static void do_jack_output(process_jack_t *j); static int do_midi_output(process_midi_t *m); static int stream_init(midi_stream_t *s, alsa_rawmidi_t *midi, const char *name) { s->owner = midi; s->name = name; if (pipe(s->wake_pipe)==-1) { s->wake_pipe[0] = -1; error_log("pipe() in stream_init(%s) failed: %s", name, strerror(errno)); return -errno; } s->jack.new_ports = jack_ringbuffer_create(sizeof(midi_port_t*)*MAX_PORTS); s->midi.new_ports = jack_ringbuffer_create(sizeof(midi_port_t*)*MAX_PORTS); if (!s->jack.new_ports || !s->midi.new_ports) return -ENOMEM; return 0; } static void stream_close(midi_stream_t *s) { if (s->wake_pipe[0] != -1) { close(s->wake_pipe[0]); close(s->wake_pipe[1]); } if (s->jack.new_ports) jack_ringbuffer_free(s->jack.new_ports); if (s->midi.new_ports) jack_ringbuffer_free(s->midi.new_ports); } static void alsa_rawmidi_delete(alsa_midi_t *m); static int alsa_rawmidi_attach(alsa_midi_t *m); static int alsa_rawmidi_detach(alsa_midi_t *m); static int alsa_rawmidi_start(alsa_midi_t *m); static int alsa_rawmidi_stop(alsa_midi_t *m); static void alsa_rawmidi_read(alsa_midi_t *m, jack_nframes_t nframes); static void alsa_rawmidi_write(alsa_midi_t *m, jack_nframes_t nframes); alsa_midi_t* alsa_rawmidi_new(jack_client_t *jack) { alsa_rawmidi_t *midi = calloc(1, sizeof(alsa_rawmidi_t)); if (!midi) goto fail_0; midi->client = jack; if (pipe(midi->scan.wake_pipe)==-1) { error_log("pipe() in alsa_midi_new failed: %s", strerror(errno)); goto fail_1; } if (stream_init(&midi->in, midi, "in")) goto fail_2; midi->in.mode = POLLIN; midi->in.port_size = sizeof(input_port_t); midi->in.port_init = input_port_init; midi->in.port_close = input_port_close; midi->in.process_jack = do_jack_input; midi->in.process_midi = do_midi_input; if (stream_init(&midi->out, midi, "out")) goto fail_3; midi->out.mode = POLLOUT; midi->out.port_size = sizeof(output_port_t); midi->out.port_init = output_port_init; midi->out.port_close = output_port_close; midi->out.process_jack = do_jack_output; midi->out.process_midi = do_midi_output; midi->ops.destroy = alsa_rawmidi_delete; midi->ops.attach = alsa_rawmidi_attach; midi->ops.detach = alsa_rawmidi_detach; midi->ops.start = alsa_rawmidi_start; midi->ops.stop = alsa_rawmidi_stop; midi->ops.read = alsa_rawmidi_read; midi->ops.write = alsa_rawmidi_write; midi->midi_in_cnt = 0; midi->midi_out_cnt = 0; return &midi->ops; fail_3: stream_close(&midi->out); fail_2: stream_close(&midi->in); close(midi->scan.wake_pipe[1]); close(midi->scan.wake_pipe[0]); fail_1: free(midi); fail_0: return NULL; } static midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list); static void alsa_rawmidi_delete(alsa_midi_t *m) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; alsa_rawmidi_detach(m); stream_close(&midi->out); stream_close(&midi->in); close(midi->scan.wake_pipe[0]); close(midi->scan.wake_pipe[1]); free(midi); } static void* scan_thread(void *); static void *midi_thread(void *arg); static int alsa_rawmidi_attach(alsa_midi_t *m) { return 0; } static int alsa_rawmidi_detach(alsa_midi_t *m) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; midi_port_t **list; alsa_rawmidi_stop(m); list = &midi->scan.ports; while (*list) { (*list)->state = PORT_REMOVED_FROM_JACK; list = scan_port_del(midi, list); } return 0; } static int alsa_rawmidi_start(alsa_midi_t *m) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; int err; char c = 'q'; if (midi->keep_walking == 1) return -EALREADY; midi->keep_walking = 1; if ((err = jack_client_create_thread(midi->client, &midi->in.thread, MIDI_THREAD_PRIO, jack_is_realtime(midi->client), midi_thread, &midi->in))) { midi->keep_walking = 0; return err; } if ((err = jack_client_create_thread(midi->client, &midi->out.thread, MIDI_THREAD_PRIO, jack_is_realtime(midi->client), midi_thread, &midi->out))) { midi->keep_walking = 0; write(midi->in.wake_pipe[1], &c, 1); pthread_join(midi->in.thread, NULL); return err; } if ((err = jack_client_create_thread(midi->client, &midi->scan.thread, 0, 0, scan_thread, midi))) { midi->keep_walking = 0; write(midi->in.wake_pipe[1], &c, 1); write(midi->out.wake_pipe[1], &c, 1); pthread_join(midi->in.thread, NULL); pthread_join(midi->out.thread, NULL); return err; } return 0; } static int alsa_rawmidi_stop(alsa_midi_t *m) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; char c = 'q'; if (midi->keep_walking == 0) return -EALREADY; midi->keep_walking = 0; write(midi->in.wake_pipe[1], &c, 1); write(midi->out.wake_pipe[1], &c, 1); write(midi->scan.wake_pipe[1], &c, 1); pthread_join(midi->in.thread, NULL); pthread_join(midi->out.thread, NULL); pthread_join(midi->scan.thread, NULL); // ports are freed in alsa_midi_detach() return 0; } static void jack_process(midi_stream_t *str, jack_nframes_t nframes); static void alsa_rawmidi_read(alsa_midi_t *m, jack_nframes_t nframes) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; jack_process(&midi->in, nframes); } static void alsa_rawmidi_write(alsa_midi_t *m, jack_nframes_t nframes) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; jack_process(&midi->out, nframes); } /* * ----------------------------------------------------------------------------- */ static inline int can_pass(size_t sz, jack_ringbuffer_t *in, jack_ringbuffer_t *out) { return jack_ringbuffer_read_space(in) >= sz && jack_ringbuffer_write_space(out) >= sz; } static void midi_port_init(const alsa_rawmidi_t *midi, midi_port_t *port, snd_rawmidi_info_t *info, const alsa_id_t *id) { const char *name; char *c; port->id = *id; snprintf(port->dev, sizeof(port->dev), "hw:%d,%d,%d", id->id[0], id->id[1], id->id[3]); name = snd_rawmidi_info_get_subdevice_name(info); if (!strlen(name)) name = snd_rawmidi_info_get_name(info); snprintf(port->name, sizeof(port->name), "%s %s %s", port->id.id[2] ? "out":"in", port->dev, name); // replace all offending characters with '-' for (c=port->name; *c; ++c) if (!isalnum(*c)) *c = '-'; port->state = PORT_CREATED; } static inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type, const char *alias) { char name[128]; if (type & JackPortIsOutput) snprintf(name, sizeof(name), "system:midi_capture_%d", ++midi->midi_in_cnt); else snprintf(name, sizeof(name), "system:midi_playback_%d", ++midi->midi_out_cnt); port->jack = jack_port_register(midi->client, name, JACK_DEFAULT_MIDI_TYPE, type | JackPortIsPhysical | JackPortIsTerminal, 0); if (port->jack) jack_port_set_alias(port->jack, alias); return port->jack == NULL; } static int midi_port_open(alsa_rawmidi_t *midi, midi_port_t *port) { int err; int type; char name[64]; snd_rawmidi_t **in = NULL; snd_rawmidi_t **out = NULL; if (port->id.id[2] == 0) { in = &port->rawmidi; type = JackPortIsOutput; } else { out = &port->rawmidi; type = JackPortIsInput; } if ((err = snd_rawmidi_open(in, out, port->dev, SND_RAWMIDI_NONBLOCK))<0) return err; /* Some devices (emu10k1) have subdevs with the same name, * and we need to generate unique port name for jack */ snprintf(name, sizeof(name), "%s", port->name); if (midi_port_open_jack(midi, port, type, name)) { int num; num = port->id.id[3] ? port->id.id[3] : port->id.id[1]; snprintf(name, sizeof(name), "%s %d", port->name, num); if (midi_port_open_jack(midi, port, type, name)) return 2; } if ((port->event_ring = jack_ringbuffer_create(MAX_EVENTS*sizeof(event_head_t)))==NULL) return 3; if ((port->data_ring = jack_ringbuffer_create(MAX_DATA))==NULL) return 4; return 0; } static void midi_port_close(const alsa_rawmidi_t *midi, midi_port_t *port) { if (port->data_ring) { jack_ringbuffer_free(port->data_ring); port->data_ring = NULL; } if (port->event_ring) { jack_ringbuffer_free(port->event_ring); port->event_ring = NULL; } if (port->jack) { jack_port_unregister(midi->client, port->jack); port->jack = NULL; } if (port->rawmidi) { snd_rawmidi_close(port->rawmidi); port->rawmidi = NULL; } } /* * ------------------------- Port scanning ------------------------------- */ static int alsa_id_before(const alsa_id_t *p1, const alsa_id_t *p2) { int i; for (i=0; i<4; ++i) { if (p1->id[i] < p2->id[i]) return 1; else if (p1->id[i] > p2->id[i]) return 0; } return 0; } static void alsa_get_id(alsa_id_t *id, snd_rawmidi_info_t *info) { id->id[0] = snd_rawmidi_info_get_card(info); id->id[1] = snd_rawmidi_info_get_device(info); id->id[2] = snd_rawmidi_info_get_stream(info) == SND_RAWMIDI_STREAM_OUTPUT ? 1 : 0; id->id[3] = snd_rawmidi_info_get_subdevice(info); } #include static inline void alsa_error(const char *func, int err) { error_log("%s() failed", snd_strerror(err)); } typedef struct { alsa_rawmidi_t *midi; midi_port_t **iterator; snd_ctl_t *ctl; snd_rawmidi_info_t *info; } scan_t; static midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list); static void scan_cleanup(alsa_rawmidi_t *midi) { midi_port_t **list = &midi->scan.ports; while (*list) list = scan_port_del(midi, list); } static void scan_card(scan_t *scan); static midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list); void scan_cycle(alsa_rawmidi_t *midi) { int card = -1, err; scan_t scan; midi_port_t **ports; //debug_log("scan: cleanup"); scan_cleanup(midi); scan.midi = midi; scan.iterator = &midi->scan.ports; snd_rawmidi_info_alloca(&scan.info); //debug_log("scan: rescan"); while ((err = snd_card_next(&card))>=0 && card>=0) { char name[32]; snprintf(name, sizeof(name), "hw:%d", card); if ((err = snd_ctl_open(&scan.ctl, name, SND_CTL_NONBLOCK))>=0) { scan_card(&scan); snd_ctl_close(scan.ctl); } else alsa_error("scan: snd_ctl_open", err); } // delayed open to workaround alsa<1.0.14 bug (can't open more than 1 subdevice if ctl is opened). ports = &midi->scan.ports; while (*ports) { midi_port_t *port = *ports; if (port->state == PORT_CREATED) ports = scan_port_open(midi, ports); else ports = &port->next; } } static void scan_device(scan_t *scan); static void scan_card(scan_t *scan) { int device = -1; int err; while ((err = snd_ctl_rawmidi_next_device(scan->ctl, &device))>=0 && device >=0) { snd_rawmidi_info_set_device(scan->info, device); snd_rawmidi_info_set_stream(scan->info, SND_RAWMIDI_STREAM_INPUT); snd_rawmidi_info_set_subdevice(scan->info, 0); if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info))>=0) scan_device(scan); else if (err != -ENOENT) alsa_error("scan: snd_ctl_rawmidi_info on device", err); snd_rawmidi_info_set_stream(scan->info, SND_RAWMIDI_STREAM_OUTPUT); snd_rawmidi_info_set_subdevice(scan->info, 0); if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info))>=0) scan_device(scan); else if (err != -ENOENT) alsa_error("scan: snd_ctl_rawmidi_info on device", err); } } static void scan_port_update(scan_t *scan); static void scan_device(scan_t *scan) { int err; int sub, nsubs = 0; nsubs = snd_rawmidi_info_get_subdevices_count(scan->info); for (sub=0; subinfo, sub); if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info)) < 0) { alsa_error("scan: snd_ctl_rawmidi_info on subdevice", err); continue; } scan_port_update(scan); } } static midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **list); static void scan_port_update(scan_t *scan) { midi_port_t **list = scan->iterator; alsa_id_t id; alsa_get_id(&id, scan->info); while (*list && alsa_id_before(&(*list)->id, &id)) list = scan_port_del(scan->midi, list); if (!*list || alsa_id_before(&id, &(*list)->id)) list = scan_port_add(scan, &id, list); else if (*list) list = &(*list)->next; scan->iterator = list; } static midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **list) { midi_port_t *port; midi_stream_t *str = id->id[2] ? &scan->midi->out : &scan->midi->in; port = calloc(1, str->port_size); if (!port) return list; midi_port_init(scan->midi, port, scan->info, id); port->next = *list; *list = port; info_log("scan: added port %s %s", port->dev, port->name); return &port->next; } static midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list) { int ret; midi_stream_t *str; midi_port_t *port; port = *list; str = port->id.id[2] ? &midi->out : &midi->in; if (jack_ringbuffer_write_space(str->jack.new_ports) < sizeof(port)) goto fail_0; ret = midi_port_open(midi, port); if (ret) goto fail_1; if ((str->port_init)(midi, port)) goto fail_2; port->state = PORT_ADDED_TO_JACK; jack_ringbuffer_write(str->jack.new_ports, (char*) &port, sizeof(port)); info_log("scan: opened port %s %s", port->dev, port->name); return &port->next; fail_2: (str->port_close)(midi, port); fail_1: midi_port_close(midi, port); port->state = PORT_ZOMBIFIED; error_log("scan: can't open port %s %s, error code %d, zombified", port->dev, port->name, ret); return &port->next; fail_0: error_log("scan: can't open port %s %s", port->dev, port->name); return &port->next; } static midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list) { midi_port_t *port = *list; if (port->state == PORT_REMOVED_FROM_JACK) { info_log("scan: deleted port %s %s", port->dev, port->name); *list = port->next; if (port->id.id[2] ) (midi->out.port_close)(midi, port); else (midi->in.port_close)(midi, port); midi_port_close(midi, port); free(port); return list; } else { //debug_log("can't delete port %s, wrong state: %d", port->name, (int)port->state); return &port->next; } } void* scan_thread(void *arg) { alsa_rawmidi_t *midi = arg; struct pollfd wakeup; wakeup.fd = midi->scan.wake_pipe[0]; wakeup.events = POLLIN|POLLERR|POLLNVAL; while (midi->keep_walking) { int res; //error_log("scanning...."); scan_cycle(midi); res = poll(&wakeup, 1, 2000); if (res>0) { char c; read(wakeup.fd, &c, 1); } else if (res<0 && errno != EINTR) break; } return NULL; } /* * ------------------------------- Input/Output ------------------------------ */ static void jack_add_ports(midi_stream_t *str) { midi_port_t *port; while (can_pass(sizeof(port), str->jack.new_ports, str->midi.new_ports) && str->jack.nports < MAX_PORTS) { jack_ringbuffer_read(str->jack.new_ports, (char*)&port, sizeof(port)); str->jack.ports[str->jack.nports++] = port; port->state = PORT_ADDED_TO_MIDI; jack_ringbuffer_write(str->midi.new_ports, (char*)&port, sizeof(port)); } } static void jack_process(midi_stream_t *str, jack_nframes_t nframes) { int r, w; process_jack_t proc; jack_nframes_t cur_frames; if (!str->owner->keep_walking) return; proc.midi = str->owner; proc.nframes = nframes; proc.frame_time = jack_last_frame_time(proc.midi->client); cur_frames = jack_frame_time(proc.midi->client); int periods_diff = cur_frames - proc.frame_time; if (periods_diff < proc.nframes) { int periods_lost = periods_diff / proc.nframes; proc.frame_time += periods_lost * proc.nframes; debug_log("xrun detected: %d periods lost", periods_lost); } // process existing ports for (r=0, w=0; rjack.nports; ++r) { midi_port_t *port = str->jack.ports[r]; proc.port = port; assert (port->state > PORT_ADDED_TO_JACK && port->state < PORT_REMOVED_FROM_JACK); proc.buffer = jack_port_get_buffer(port->jack, nframes); if (str->mode == POLLIN) jack_midi_clear_buffer(proc.buffer); if (port->state == PORT_REMOVED_FROM_MIDI) { port->state = PORT_REMOVED_FROM_JACK; // this signals to scan thread continue; // this effectively removes port from the midi->in.jack.ports[] } (str->process_jack)(&proc); if (r != w) str->jack.ports[w] = port; ++w; } if (str->jack.nports != w) { debug_log("jack_%s: nports %d -> %d", str->name, str->jack.nports, w); } str->jack.nports = w; jack_add_ports(str); // it makes no sense to add them earlier since they have no data yet // wake midi thread write(str->wake_pipe[1], &r, 1); } static void *midi_thread(void *arg) { midi_stream_t *str = arg; alsa_rawmidi_t *midi = str->owner; struct pollfd pfds[MAX_PFDS]; int npfds; jack_time_t wait_nsec = 1000*1000*1000; // 1 sec process_midi_t proc; proc.midi = midi; proc.mode = str->mode; pfds[0].fd = str->wake_pipe[0]; pfds[0].events = POLLIN|POLLERR|POLLNVAL; npfds = 1; if (jack_is_realtime(midi->client)) set_threaded_log_function(); //debug_log("midi_thread(%s): enter", str->name); while (midi->keep_walking) { int poll_timeout; int wait_nanosleep; int r=1, w=1; // read,write pos in pfds int rp=0, wp=0; // read, write pos in ports // sleep //if (wait_nsec != 1000*1000*1000) { // debug_log("midi_thread(%s): ", str->name); // assert (wait_nsec == 1000*1000*1000); //} poll_timeout = wait_nsec / (1000*1000); wait_nanosleep = wait_nsec % (1000*1000); if (wait_nanosleep > NANOSLEEP_RESOLUTION) { struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = wait_nanosleep; clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); } int res = poll((struct pollfd*)&pfds, npfds, poll_timeout); //debug_log("midi_thread(%s): poll exit: %d", str->name, res); if (!midi->keep_walking) break; if (res < 0) { if (errno == EINTR) continue; error_log("midi_thread(%s) poll failed: %s", str->name, strerror(errno)); break; } // check wakeup pipe if (pfds[0].revents & ~POLLIN) break; if (pfds[0].revents & POLLIN) { char c; read(pfds[0].fd, &c, 1); } // add new ports while (jack_ringbuffer_read_space(str->midi.new_ports) >= sizeof(midi_port_t*) && str->midi.nports < MAX_PORTS) { midi_port_t *port; jack_ringbuffer_read(str->midi.new_ports, (char*)&port, sizeof(port)); str->midi.ports[str->midi.nports++] = port; debug_log("midi_thread(%s): added port %s", str->name, port->name); } // if (res == 0) // continue; // process ports proc.cur_time = 0; //jack_frame_time(midi->client); proc.next_time = NFRAMES_INF; for (rp = 0; rp < str->midi.nports; ++rp) { midi_port_t *port = str->midi.ports[rp]; proc.cur_time = jack_frame_time(midi->client); proc.port = port; proc.rpfds = &pfds[r]; proc.wpfds = &pfds[w]; proc.max_pfds = MAX_PFDS - w; r += port->npfds; if (!(str->process_midi)(&proc)) { port->state = PORT_REMOVED_FROM_MIDI; // this signals to jack thread continue; // this effectively removes port from array } w += port->npfds; if (rp != wp) str->midi.ports[wp] = port; ++wp; } if (str->midi.nports != wp) { debug_log("midi_%s: nports %d -> %d", str->name, str->midi.nports, wp); } str->midi.nports = wp; if (npfds != w) { debug_log("midi_%s: npfds %d -> %d", str->name, npfds, w); } npfds = w; /* * Input : ports do not set proc.next_time. * Output: port sets proc.next_time ONLY if it does not have queued data. * So, zero timeout will not cause busy-looping. */ if (proc.next_time < proc.cur_time) { debug_log("%s: late: next_time = %d, cur_time = %d", str->name, (int)proc.next_time, (int)proc.cur_time); wait_nsec = 0; // we are late } else if (proc.next_time != NFRAMES_INF) { jack_time_t wait_frames = proc.next_time - proc.cur_time; jack_nframes_t rate = jack_get_sample_rate(midi->client); wait_nsec = (wait_frames * (1000*1000*1000)) / rate; debug_log("midi_%s: timeout = %d", str->name, (int)wait_frames); } else wait_nsec = 1000*1000*1000; //debug_log("midi_thread(%s): wait_nsec = %lld", str->name, wait_nsec); } return NULL; } static int midi_is_ready(process_midi_t *proc) { midi_port_t *port = proc->port; if (port->npfds) { unsigned short revents = 0; int res = snd_rawmidi_poll_descriptors_revents(port->rawmidi, proc->rpfds, port->npfds, &revents); if (res) { error_log("snd_rawmidi_poll_descriptors_revents failed on port %s with: %s", port->name, snd_strerror(res)); return 0; } if (revents & ~proc->mode) { debug_log("midi: port %s failed", port->name); return 0; } if (revents & proc->mode) { port->is_ready = 1; debug_log("midi: is_ready %s", port->name); } } return 1; } static int midi_update_pfds(process_midi_t *proc) { midi_port_t *port = proc->port; if (port->npfds == 0) { port->npfds = snd_rawmidi_poll_descriptors_count(port->rawmidi); if (port->npfds > proc->max_pfds) { debug_log("midi: not enough pfds for port %s", port->name); return 0; } snd_rawmidi_poll_descriptors(port->rawmidi, proc->wpfds, port->npfds); } else if (proc->rpfds != proc->wpfds) { memmove(proc->wpfds, proc->rpfds, sizeof(struct pollfd) * port->npfds); } return 1; } /* * ------------------------------------ Input ------------------------------ */ static int input_port_init(alsa_rawmidi_t *midi, midi_port_t *port) { input_port_t *in = (input_port_t*)port; midi_unpack_init(&in->unpack); return 0; } static void input_port_close(alsa_rawmidi_t *midi, midi_port_t *port) {} /* * Jack-level input. */ static void do_jack_input(process_jack_t *p) { input_port_t *port = (input_port_t*) p->port; event_head_t event; while (jack_ringbuffer_read_space(port->base.event_ring) >= sizeof(event)) { jack_ringbuffer_data_t vec[2]; jack_nframes_t time; int i, todo; jack_ringbuffer_read(port->base.event_ring, (char*)&event, sizeof(event)); // TODO: take into account possible warping if ((event.time + p->nframes) < p->frame_time) time = 0; else if (event.time >= p->frame_time) time = p->nframes -1; else time = event.time + p->nframes - p->frame_time; jack_ringbuffer_get_read_vector(port->base.data_ring, vec); assert ((vec[0].len + vec[1].len) >= event.size); if (event.overruns) midi_unpack_reset(&port->unpack); todo = event.size; for (i=0; i<2 && todo>0; ++i) { int avail = todo < vec[i].len ? todo : vec[i].len; int done = midi_unpack_buf(&port->unpack, (unsigned char*)vec[i].buf, avail, p->buffer, time); if (done != avail) { debug_log("jack_in: buffer overflow in port %s", port->base.name); break; } todo -= done; } jack_ringbuffer_read_advance(port->base.data_ring, event.size); } } /* * Low level input. */ static int do_midi_input(process_midi_t *proc) { input_port_t *port = (input_port_t*) proc->port; if (!midi_is_ready(proc)) return 0; if (port->base.is_ready) { jack_ringbuffer_data_t vec[2]; int res; jack_ringbuffer_get_write_vector(port->base.data_ring, vec); if (jack_ringbuffer_write_space(port->base.event_ring) < sizeof(event_head_t) || vec[0].len < 1) { port->overruns++; if (port->base.npfds) { debug_log("midi_in: internal overflow on %s", port->base.name); } // remove from poll to prevent busy-looping port->base.npfds = 0; return 1; } res = snd_rawmidi_read(port->base.rawmidi, vec[0].buf, vec[0].len); if (res < 0 && res != -EWOULDBLOCK) { error_log("midi_in: reading from port %s failed: %s", port->base.name, snd_strerror(res)); return 0; } else if (res > 0) { event_head_t event; event.time = proc->cur_time; event.size = res; event.overruns = port->overruns; port->overruns = 0; debug_log("midi_in: read %d bytes at %d", (int)event.size, (int)event.time); jack_ringbuffer_write_advance(port->base.data_ring, event.size); jack_ringbuffer_write(port->base.event_ring, (char*)&event, sizeof(event)); } port->base.is_ready = 0; } if (!midi_update_pfds(proc)) return 0; return 1; } /* * ------------------------------------ Output ------------------------------ */ static int output_port_init(alsa_rawmidi_t *midi, midi_port_t *port) { output_port_t *out = (output_port_t*)port; midi_pack_reset(&out->packer); out->next_event.time = 0; out->next_event.size = 0; out->todo = 0; return 0; } static void output_port_close(alsa_rawmidi_t *midi, midi_port_t *port) {} static void do_jack_output(process_jack_t *proc) { output_port_t *port = (output_port_t*) proc->port; int nevents = jack_midi_get_event_count(proc->buffer); int i; if (nevents) { debug_log("jack_out: %d events in %s", nevents, port->base.name); } for (i=0; ibuffer, i); if (jack_ringbuffer_write_space(port->base.data_ring) < event.size || jack_ringbuffer_write_space(port->base.event_ring) < sizeof(hdr)) { debug_log("jack_out: output buffer overflow on %s", port->base.name); break; } midi_pack_event(&port->packer, &event); jack_ringbuffer_write(port->base.data_ring, (char*)event.buffer, event.size); hdr.time = proc->frame_time + event.time + proc->nframes; hdr.size = event.size; jack_ringbuffer_write(port->base.event_ring, (char*)&hdr, sizeof(hdr)); debug_log("jack_out: sent %d-byte event at %ld", (int)event.size, (long)event.time); } } static int do_midi_output(process_midi_t *proc) { int worked = 0; output_port_t *port = (output_port_t*) proc->port; if (!midi_is_ready(proc)) return 0; // eat events while (port->next_event.time <= proc->cur_time) { port->todo += port->next_event.size; if (jack_ringbuffer_read(port->base.event_ring, (char*)&port->next_event, sizeof(port->next_event))!=sizeof(port->next_event)) { port->next_event.time = 0; port->next_event.size = 0; break; } else { debug_log("midi_out: at %ld got %d bytes for %ld", (long)proc->cur_time, (int)port->next_event.size, (long)port->next_event.time); } } if (port->todo) { debug_log("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time); } // calc next wakeup time if (!port->todo && port->next_event.time && port->next_event.time < proc->next_time) { proc->next_time = port->next_event.time; debug_log("midi_out: next_time = %ld", (long)proc->next_time); } if (port->todo && port->base.is_ready) { // write data int size = port->todo; int res; jack_ringbuffer_data_t vec[2]; jack_ringbuffer_get_read_vector(port->base.data_ring, vec); if (size > vec[0].len) { size = vec[0].len; assert (size > 0); } res = snd_rawmidi_write(port->base.rawmidi, vec[0].buf, size); if (res > 0) { jack_ringbuffer_read_advance(port->base.data_ring, res); debug_log("midi_out: written %d bytes to %s", res, port->base.name); port->todo -= res; worked = 1; } else if (res == -EWOULDBLOCK) { port->base.is_ready = 0; debug_log("midi_out: -EWOULDBLOCK on %s", port->base.name); return 1; } else { error_log("midi_out: writing to port %s failed: %s", port->base.name, snd_strerror(res)); return 0; } snd_rawmidi_drain(port->base.rawmidi); } // update pfds for this port if (!midi_update_pfds(proc)) return 0; if (!port->todo) { int i; if (worked) { debug_log("midi_out: relaxing on %s", port->base.name); } for (i=0; ibase.npfds; ++i) proc->wpfds[i].events &= ~POLLOUT; } else { int i; for (i=0; ibase.npfds; ++i) proc->wpfds[i].events |= POLLOUT; } return 1; } 1.9.12~dfsg/linux/alsa/ice1712.h0000644000000000000000000000477613214314510014661 0ustar rootroot/* Copyright (C) 2002 Anthony Van Groningen Parts based on source code taken from the "Env24 chipset (ICE1712) control utility" that is Copyright (C) 2000 by Jaroslav Kysela This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __jack_ice1712_h__ #define __jack_ice1712_h__ #define ICE1712_SUBDEVICE_DELTA44 0x121433d6 #define ICE1712_SUBDEVICE_DELTA66 0x121432d6 #define ICE1712_SUBDEVICE_DELTA1010 0x121430d6 #define ICE1712_SUBDEVICE_DELTADIO2496 0x121431d6 #define ICE1712_SUBDEVICE_AUDIOPHILE 0x121434d6 #define SPDIF_PLAYBACK_ROUTE_NAME "IEC958 Playback Route" #define ANALOG_PLAYBACK_ROUTE_NAME "H/W Playback Route" #define MULTITRACK_PEAK_NAME "Multi Track Peak" typedef struct { unsigned int subvendor; /* PCI[2c-2f] */ unsigned char size; /* size of EEPROM image in bytes */ unsigned char version; /* must be 1 */ unsigned char codec; /* codec configuration PCI[60] */ unsigned char aclink; /* ACLink configuration PCI[61] */ unsigned char i2sID; /* PCI[62] */ unsigned char spdif; /* S/PDIF configuration PCI[63] */ unsigned char gpiomask; /* GPIO initial mask, 0 = write, 1 = don't */ unsigned char gpiostate; /* GPIO initial state */ unsigned char gpiodir; /* GPIO direction state */ unsigned short ac97main; unsigned short ac97pcm; unsigned short ac97rec; unsigned char ac97recsrc; unsigned char dacID[4]; /* I2S IDs for DACs */ unsigned char adcID[4]; /* I2S IDs for ADCs */ unsigned char extra[4]; } ice1712_eeprom_t; typedef struct { alsa_driver_t *driver; ice1712_eeprom_t *eeprom; unsigned long active_channels; } ice1712_t; #ifdef __cplusplus extern "C" { #endif jack_hardware_t *jack_alsa_ice1712_hw_new (alsa_driver_t *driver); #ifdef __cplusplus } #endif #endif /* __jack_ice1712_h__*/ 1.9.12~dfsg/linux/alsa/usx2y.h0000644000000000000000000000360313214314510014664 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Karsten Wiese, Rui Nuno Capela This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: usx2y.h 855 2004-12-28 05:50:18Z joq $ */ #ifndef __jack_usx2y_h__ #define __jack_usx2y_h__ #define USX2Y_MAXPACK 50 #define USX2Y_MAXBUFFERMS 100 #define USX2Y_MAXSTRIDE 3 #define USX2Y_SSS (((USX2Y_MAXPACK * USX2Y_MAXBUFFERMS * USX2Y_MAXSTRIDE + 4096) / 4096) * 4096) struct snd_usX2Y_hwdep_pcm_shm { char playback[USX2Y_SSS]; char capture0x8[USX2Y_SSS]; char capture0xA[USX2Y_SSS]; volatile int playback_iso_head; int playback_iso_start; struct { int frame, offset, length; } captured_iso[128]; volatile int captured_iso_head; volatile unsigned captured_iso_frames; int capture_iso_start; }; typedef struct snd_usX2Y_hwdep_pcm_shm snd_usX2Y_hwdep_pcm_shm_t; typedef struct { alsa_driver_t *driver; snd_hwdep_t *hwdep_handle; struct pollfd pfds; struct snd_usX2Y_hwdep_pcm_shm *hwdep_pcm_shm; int playback_iso_start; int playback_iso_bytes_done; int capture_iso_start; int capture_iso_bytes_done; } usx2y_t; jack_hardware_t * jack_alsa_usx2y_hw_new (alsa_driver_t *driver); #endif /* __jack_usx2y_h__*/ 1.9.12~dfsg/linux/alsa/alsa_driver.h0000644000000000000000000002132013214314510016061 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: alsa_driver.h 945 2006-05-04 15:14:45Z pbd $ */ #ifndef __jack_alsa_driver_h__ #define __jack_alsa_driver_h__ #include #include "bitset.h" #if __BYTE_ORDER == __LITTLE_ENDIAN #define IS_LE 0 #define IS_BE 1 #elif __BYTE_ORDER == __BIG_ENDIAN #define IS_LE 1 #define IS_BE 0 #endif #define TRUE 1 #define FALSE 0 #include "types.h" #include "hardware.h" #include "driver.h" #include "memops.h" #include "alsa_midi.h" #ifdef __cplusplus extern "C" { #endif typedef void (*ReadCopyFunction) (jack_default_audio_sample_t *dst, char *src, unsigned long src_bytes, unsigned long src_skip_bytes); typedef void (*WriteCopyFunction) (char *dst, jack_default_audio_sample_t *src, unsigned long src_bytes, unsigned long dst_skip_bytes, dither_state_t *state); typedef struct _alsa_driver { JACK_DRIVER_NT_DECL int poll_timeout; jack_time_t poll_last; jack_time_t poll_next; char **playback_addr; char **capture_addr; const snd_pcm_channel_area_t *capture_areas; const snd_pcm_channel_area_t *playback_areas; struct pollfd *pfd; unsigned int playback_nfds; unsigned int capture_nfds; unsigned long interleave_unit; unsigned long *capture_interleave_skip; unsigned long *playback_interleave_skip; channel_t max_nchannels; channel_t user_nchannels; channel_t playback_nchannels; channel_t capture_nchannels; unsigned long playback_sample_bytes; unsigned long capture_sample_bytes; jack_nframes_t frame_rate; jack_nframes_t frames_per_cycle; jack_nframes_t capture_frame_latency; jack_nframes_t playback_frame_latency; unsigned long *silent; char *alsa_name_playback; char *alsa_name_capture; char *alsa_driver; bitset_t channels_not_done; bitset_t channels_done; snd_pcm_format_t playback_sample_format; snd_pcm_format_t capture_sample_format; float max_sample_val; unsigned long user_nperiods; unsigned int playback_nperiods; unsigned int capture_nperiods; unsigned long last_mask; snd_ctl_t *ctl_handle; snd_pcm_t *playback_handle; snd_pcm_t *capture_handle; snd_pcm_hw_params_t *playback_hw_params; snd_pcm_sw_params_t *playback_sw_params; snd_pcm_hw_params_t *capture_hw_params; snd_pcm_sw_params_t *capture_sw_params; jack_hardware_t *hw; ClockSyncStatus *clock_sync_data; jack_client_t *client; JSList *capture_ports; JSList *playback_ports; JSList *monitor_ports; unsigned long input_monitor_mask; char soft_mode; char hw_monitoring; char hw_metering; char all_monitor_in; char capture_and_playback_not_synced; char playback_interleaved; char capture_interleaved; char with_monitor_ports; char has_clock_sync_reporting; char has_hw_monitoring; char has_hw_metering; char quirk_bswap; ReadCopyFunction read_via_copy; WriteCopyFunction write_via_copy; int dither; dither_state_t *dither_state; SampleClockMode clock_mode; JSList *clock_sync_listeners; pthread_mutex_t clock_sync_lock; unsigned long next_clock_sync_listener_id; int running; int run; int poll_late; int xrun_count; int process_count; alsa_midi_t *midi; int xrun_recovery; } alsa_driver_t; static inline void alsa_driver_mark_channel_done (alsa_driver_t *driver, channel_t chn) { bitset_remove (driver->channels_not_done, chn); driver->silent[chn] = 0; } static inline void alsa_driver_silence_on_channel (alsa_driver_t *driver, channel_t chn, jack_nframes_t nframes) { if (driver->playback_interleaved) { memset_interleave (driver->playback_addr[chn], 0, nframes * driver->playback_sample_bytes, driver->interleave_unit, driver->playback_interleave_skip[chn]); } else { memset (driver->playback_addr[chn], 0, nframes * driver->playback_sample_bytes); } alsa_driver_mark_channel_done (driver,chn); } static inline void alsa_driver_silence_on_channel_no_mark (alsa_driver_t *driver, channel_t chn, jack_nframes_t nframes) { if (driver->playback_interleaved) { memset_interleave (driver->playback_addr[chn], 0, nframes * driver->playback_sample_bytes, driver->interleave_unit, driver->playback_interleave_skip[chn]); } else { memset (driver->playback_addr[chn], 0, nframes * driver->playback_sample_bytes); } } static inline void alsa_driver_read_from_channel (alsa_driver_t *driver, channel_t channel, jack_default_audio_sample_t *buf, jack_nframes_t nsamples) { driver->read_via_copy (buf, driver->capture_addr[channel], nsamples, driver->capture_interleave_skip[channel]); } static inline void alsa_driver_write_to_channel (alsa_driver_t *driver, channel_t channel, jack_default_audio_sample_t *buf, jack_nframes_t nsamples) { driver->write_via_copy (driver->playback_addr[channel], buf, nsamples, driver->playback_interleave_skip[channel], driver->dither_state+channel); alsa_driver_mark_channel_done (driver, channel); } void alsa_driver_silence_untouched_channels (alsa_driver_t *driver, jack_nframes_t nframes); void alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn, ClockSyncStatus status); int alsa_driver_listen_for_clock_sync_status (alsa_driver_t *, ClockSyncListenerFunction, void *arg); int alsa_driver_stop_listen_for_clock_sync_status (alsa_driver_t *, unsigned int); void alsa_driver_clock_sync_notify (alsa_driver_t *, channel_t chn, ClockSyncStatus); int alsa_driver_reset_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cycle, jack_nframes_t user_nperiods, jack_nframes_t rate); jack_driver_t * alsa_driver_new (char *name, char *playback_alsa_device, char *capture_alsa_device, jack_client_t *client, jack_nframes_t frames_per_cycle, jack_nframes_t user_nperiods, jack_nframes_t rate, int hw_monitoring, int hw_metering, int capturing, int playing, DitherAlgorithm dither, int soft_mode, int monitor, int user_capture_nchnls, int user_playback_nchnls, int shorts_first, jack_nframes_t capture_latency, jack_nframes_t playback_latency, alsa_midi_t *midi_driver ); void alsa_driver_delete (alsa_driver_t *driver); int alsa_driver_start (alsa_driver_t *driver); int alsa_driver_stop (alsa_driver_t *driver); jack_nframes_t alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delayed_usecs); int alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes); int alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes); jack_time_t jack_get_microseconds(void); // Code implemented in JackAlsaDriver.cpp void ReadInput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nread); void MonitorInput(); void ClearOutput(); void WriteOutput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten); void SetTime(jack_time_t time); int Restart(); #ifdef __cplusplus } #endif #endif /* __jack_alsa_driver_h__ */ 1.9.12~dfsg/linux/alsa/usx2y.c0000644000000000000000000004464113214314510014666 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2005 Karsten Wiese, Rui Nuno Capela This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "hardware.h" #include "alsa_driver.h" #include "usx2y.h" #include #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif //#define DBGHWDEP #ifdef DBGHWDEP int dbg_offset; char dbg_buffer[8096]; #endif static int usx2y_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) { return -1; } static int usx2y_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) { return -1; } static void usx2y_release (jack_hardware_t *hw) { usx2y_t *h = (usx2y_t *) hw->private_hw; if (h == 0) return; if (h->hwdep_handle) snd_hwdep_close(h->hwdep_handle); free(h); } static int usx2y_driver_get_channel_addresses_playback (alsa_driver_t *driver, snd_pcm_uframes_t *playback_avail) { channel_t chn; int iso; snd_pcm_uframes_t playback_iso_avail; char *playback; usx2y_t *h = (usx2y_t *) driver->hw->private_hw; if (0 > h->playback_iso_start) { int bytes = driver->playback_sample_bytes * 2 * driver->frames_per_cycle * driver->user_nperiods; iso = h->hwdep_pcm_shm->playback_iso_start; if (0 > iso) return 0; /* FIXME: return -1; */ if (++iso >= ARRAY_SIZE(h->hwdep_pcm_shm->captured_iso)) iso = 0; while((bytes -= h->hwdep_pcm_shm->captured_iso[iso].length) > 0) if (++iso >= ARRAY_SIZE(h->hwdep_pcm_shm->captured_iso)) iso = 0; h->playback_iso_bytes_done = h->hwdep_pcm_shm->captured_iso[iso].length + bytes; #ifdef DBGHWDEP dbg_offset = sprintf(dbg_buffer, "first iso = %i %i@%p:%i\n", iso, h->hwdep_pcm_shm->captured_iso[iso].length, h->hwdep_pcm_shm->playback, h->hwdep_pcm_shm->captured_iso[iso].offset); #endif } else { iso = h->playback_iso_start; } #ifdef DBGHWDEP dbg_offset += sprintf(dbg_buffer + dbg_offset, "iso = %i(%i;%i); ", iso, h->hwdep_pcm_shm->captured_iso[iso].offset, h->hwdep_pcm_shm->captured_iso[iso].frame); #endif playback = h->hwdep_pcm_shm->playback + h->hwdep_pcm_shm->captured_iso[iso].offset + h->playback_iso_bytes_done; playback_iso_avail = (h->hwdep_pcm_shm->captured_iso[iso].length - h->playback_iso_bytes_done) / (driver->playback_sample_bytes * 2); if (*playback_avail >= playback_iso_avail) { *playback_avail = playback_iso_avail; if (++iso >= ARRAY_SIZE(h->hwdep_pcm_shm->captured_iso)) iso = 0; h->playback_iso_bytes_done = 0; } else h->playback_iso_bytes_done = *playback_avail * (driver->playback_sample_bytes * 2); h->playback_iso_start = iso; for (chn = 0; chn < driver->playback_nchannels; chn++) { const snd_pcm_channel_area_t *a = &driver->playback_areas[chn]; driver->playback_addr[chn] = playback + a->first / 8; } #ifdef DBGHWDEP if (dbg_offset < (sizeof(dbg_buffer) - 256)) dbg_offset += sprintf(dbg_buffer + dbg_offset, "avail %li@%p\n", *playback_avail, driver->playback_addr[0]); else { printf(dbg_buffer); return -1; } #endif return 0; } static int usx2y_driver_get_channel_addresses_capture (alsa_driver_t *driver, snd_pcm_uframes_t *capture_avail) { channel_t chn; int iso; snd_pcm_uframes_t capture_iso_avail; int capture_offset; usx2y_t *h = (usx2y_t *) driver->hw->private_hw; if (0 > h->capture_iso_start) { iso = h->hwdep_pcm_shm->capture_iso_start; if (0 > iso) return 0; /* FIXME: return -1; */ h->capture_iso_bytes_done = 0; #ifdef DBGHWDEP dbg_offset = sprintf(dbg_buffer, "cfirst iso = %i %i@%p:%i\n", iso, h->hwdep_pcm_shm->captured_iso[iso].length, h->hwdep_pcm_shm->capture0x8, h->hwdep_pcm_shm->captured_iso[iso].offset); #endif } else { iso = h->capture_iso_start; } #ifdef DBGHWDEP dbg_offset += sprintf(dbg_buffer + dbg_offset, "ciso = %i(%i;%i); ", iso, h->hwdep_pcm_shm->captured_iso[iso].offset, h->hwdep_pcm_shm->captured_iso[iso].frame); #endif capture_offset = h->hwdep_pcm_shm->captured_iso[iso].offset + h->capture_iso_bytes_done; capture_iso_avail = (h->hwdep_pcm_shm->captured_iso[iso].length - h->capture_iso_bytes_done) / (driver->capture_sample_bytes * 2); if (*capture_avail >= capture_iso_avail) { *capture_avail = capture_iso_avail; if (++iso >= ARRAY_SIZE(h->hwdep_pcm_shm->captured_iso)) iso = 0; h->capture_iso_bytes_done = 0; } else h->capture_iso_bytes_done = *capture_avail * (driver->capture_sample_bytes * 2); h->capture_iso_start = iso; for (chn = 0; chn < driver->capture_nchannels; chn++) { driver->capture_addr[chn] = (chn < 2 ? h->hwdep_pcm_shm->capture0x8 : h->hwdep_pcm_shm->capture0xA) + capture_offset + ((chn & 1) ? driver->capture_sample_bytes : 0); } #ifdef DBGHWDEP { int f = 0; unsigned *u = driver->capture_addr[0]; static unsigned last; dbg_offset += sprintf(dbg_buffer + dbg_offset, "\nvon %6u bis %6u\n", last, u[0]); while (f < *capture_avail && dbg_offset < (sizeof(dbg_buffer) - 256)) { if (u[f] != last + 1) dbg_offset += sprintf(dbg_buffer + dbg_offset, "\nooops %6u %6u\n", last, u[f]); last = u[f++]; } } if (dbg_offset < (sizeof(dbg_buffer) - 256)) dbg_offset += sprintf(dbg_buffer + dbg_offset, "avail %li@%p\n", *capture_avail, driver->capture_addr[0]); else { printf(dbg_buffer); return -1; } #endif return 0; } static int usx2y_driver_start (alsa_driver_t *driver) { int err, i; snd_pcm_uframes_t poffset, pavail; usx2y_t *h = (usx2y_t *) driver->hw->private_hw; for (i = 0; i < driver->capture_nchannels; i++) // US428 channels 3+4 are on a seperate 2 channel stream. // ALSA thinks its 1 stream with 4 channels. driver->capture_interleave_skip[i] = 2 * driver->capture_sample_bytes; driver->playback_interleave_skip[0] = 2 * driver->playback_sample_bytes; driver->playback_interleave_skip[1] = 2 * driver->playback_sample_bytes; driver->poll_last = 0; driver->poll_next = 0; if ((err = snd_pcm_prepare (driver->playback_handle)) < 0) { jack_error ("ALSA/USX2Y: prepare error for playback: %s", snd_strerror(err)); return -1; } if (driver->midi && !driver->xrun_recovery) (driver->midi->start)(driver->midi); if (driver->playback_handle) { /* int i, j; */ /* char buffer[2000]; */ h->playback_iso_start = h->capture_iso_start = -1; snd_hwdep_poll_descriptors(h->hwdep_handle, &h->pfds, 1); h->hwdep_pcm_shm = (snd_usX2Y_hwdep_pcm_shm_t*) mmap(NULL, sizeof(snd_usX2Y_hwdep_pcm_shm_t), PROT_READ, MAP_SHARED, h->pfds.fd, 0); if (MAP_FAILED == h->hwdep_pcm_shm) { perror("ALSA/USX2Y: mmap"); return -1; } if (mprotect(h->hwdep_pcm_shm->playback, sizeof(h->hwdep_pcm_shm->playback), PROT_READ|PROT_WRITE)) { perror("ALSA/USX2Y: mprotect"); return -1; } memset(h->hwdep_pcm_shm->playback, 0, sizeof(h->hwdep_pcm_shm->playback)); /* for (i = 0, j = 0; i < 2000;) { */ /* j += sprintf(buffer + j, "%04hX ", */ /* *(unsigned short*)(h->hwdep_pcm_shm->capture + i)); */ /* if (((i += 2) % 32) == 0) { */ /* jack_error(buffer); */ /* j = 0; */ /* } */ /* } */ } if (driver->hw_monitoring) { driver->hw->set_input_monitor_mask (driver->hw, driver->input_monitor_mask); } if (driver->playback_handle) { /* fill playback buffer with zeroes, and mark all fragments as having data. */ pavail = snd_pcm_avail_update (driver->playback_handle); if (pavail != driver->frames_per_cycle * driver->playback_nperiods) { jack_error ("ALSA/USX2Y: full buffer not available at start"); return -1; } if (snd_pcm_mmap_begin( driver->playback_handle, &driver->playback_areas, &poffset, &pavail) < 0) { return -1; } /* XXX this is cheating. ALSA offers no guarantee that we can access the entire buffer at any one time. It works on most hardware tested so far, however, buts its a liability in the long run. I think that alsa-lib may have a better function for doing this here, where the goal is to silence the entire buffer. */ { /* snd_pcm_uframes_t frag, nframes = driver->buffer_frames; */ /* while (nframes) { */ /* frag = nframes; */ /* if (usx2y_driver_get_channel_addresses_playback(driver, &frag) < 0) */ /* return -1; */ /* for (chn = 0; chn < driver->playback_nchannels; chn++) */ /* alsa_driver_silence_on_channel (driver, chn, frag); */ /* nframes -= frag; */ /* } */ } snd_pcm_mmap_commit (driver->playback_handle, poffset, driver->user_nperiods * driver->frames_per_cycle); if ((err = snd_pcm_start (driver->playback_handle)) < 0) { jack_error ("ALSA/USX2Y: could not start playback (%s)", snd_strerror (err)); return -1; } } if (driver->hw_monitoring && (driver->input_monitor_mask || driver->all_monitor_in)) { if (driver->all_monitor_in) { driver->hw->set_input_monitor_mask (driver->hw, ~0U); } else { driver->hw->set_input_monitor_mask ( driver->hw, driver->input_monitor_mask); } } driver->playback_nfds = snd_pcm_poll_descriptors_count (driver->playback_handle); driver->capture_nfds = snd_pcm_poll_descriptors_count (driver->capture_handle); if (driver->pfd) { free (driver->pfd); } driver->pfd = (struct pollfd *) malloc (sizeof (struct pollfd) * (driver->playback_nfds + driver->capture_nfds + 2)); return 0; } static int usx2y_driver_stop (alsa_driver_t *driver) { int err; JSList* node; int chn; usx2y_t *h = (usx2y_t *) driver->hw->private_hw; /* silence all capture port buffers, because we might be entering offline mode. */ for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { jack_port_t* port; char* buf; jack_nframes_t nframes = driver->engine->control->buffer_size; port = (jack_port_t *) node->data; buf = jack_port_get_buffer (port, nframes); memset (buf, 0, sizeof (jack_default_audio_sample_t) * nframes); } if (driver->playback_handle) { if ((err = snd_pcm_drop (driver->playback_handle)) < 0) { jack_error ("ALSA/USX2Y: channel flush for playback " "failed (%s)", snd_strerror (err)); return -1; } } if (driver->hw_monitoring) { driver->hw->set_input_monitor_mask (driver->hw, 0); } munmap(h->hwdep_pcm_shm, sizeof(snd_usX2Y_hwdep_pcm_shm_t)); if (driver->midi && !driver->xrun_recovery) (driver->midi->stop)(driver->midi); return 0; } static int usx2y_driver_null_cycle (alsa_driver_t* driver, jack_nframes_t nframes) { jack_nframes_t nf; snd_pcm_uframes_t offset; snd_pcm_uframes_t contiguous, contiguous_; int chn; VERBOSE(driver->engine, "usx2y_driver_null_cycle (%p, %i)", driver, nframes); if (driver->capture_handle) { nf = nframes; offset = 0; while (nf) { contiguous = (nf > driver->frames_per_cycle) ? driver->frames_per_cycle : nf; if (snd_pcm_mmap_begin ( driver->capture_handle, &driver->capture_areas, (snd_pcm_uframes_t *) &offset, (snd_pcm_uframes_t *) &contiguous)) { return -1; } contiguous_ = contiguous; while (contiguous_) { snd_pcm_uframes_t frag = contiguous_; if (usx2y_driver_get_channel_addresses_capture(driver, &frag) < 0) return -1; contiguous_ -= frag; } if (snd_pcm_mmap_commit (driver->capture_handle, offset, contiguous) < 0) { return -1; } nf -= contiguous; } } if (driver->playback_handle) { nf = nframes; offset = 0; while (nf) { contiguous = (nf > driver->frames_per_cycle) ? driver->frames_per_cycle : nf; if (snd_pcm_mmap_begin ( driver->playback_handle, &driver->playback_areas, (snd_pcm_uframes_t *) &offset, (snd_pcm_uframes_t *) &contiguous)) { return -1; } { snd_pcm_uframes_t frag, nframes = contiguous; while (nframes) { frag = nframes; if (usx2y_driver_get_channel_addresses_playback(driver, &frag) < 0) return -1; for (chn = 0; chn < driver->playback_nchannels; chn++) alsa_driver_silence_on_channel (driver, chn, frag); nframes -= frag; } } if (snd_pcm_mmap_commit (driver->playback_handle, offset, contiguous) < 0) { return -1; } nf -= contiguous; } } return 0; } static int usx2y_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) { snd_pcm_uframes_t contiguous; snd_pcm_sframes_t nread; snd_pcm_uframes_t offset; jack_default_audio_sample_t* buf[4]; channel_t chn; JSList *node; jack_port_t* port; int err; snd_pcm_uframes_t nframes_ = nframes; if (!driver->capture_handle || driver->engine->freewheeling) { return 0; } if (driver->midi) (driver->midi->read)(driver->midi, nframes); nread = 0; if (snd_pcm_mmap_begin (driver->capture_handle, &driver->capture_areas, &offset, &nframes_) < 0) { jack_error ("ALSA/USX2Y: %s: mmap areas info error", driver->alsa_name_capture); return -1; } for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { port = (jack_port_t *) node->data; if (!jack_port_connected (port)) { continue; } buf[chn] = jack_port_get_buffer (port, nframes_); } while (nframes) { contiguous = nframes; if (usx2y_driver_get_channel_addresses_capture ( driver, &contiguous) < 0) { return -1; } for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { port = (jack_port_t *) node->data; if (!jack_port_connected (port)) { /* no-copy optimization */ continue; } alsa_driver_read_from_channel (driver, chn, buf[chn] + nread, contiguous); /* sample_move_dS_s24(buf[chn] + nread, */ /* driver->capture_addr[chn], */ /* contiguous, */ /* driver->capture_interleave_skip); */ } nread += contiguous; nframes -= contiguous; } if ((err = snd_pcm_mmap_commit (driver->capture_handle, offset, nframes_)) < 0) { jack_error ("ALSA/USX2Y: could not complete read of %" PRIu32 " frames: error = %d", nframes_, err); return -1; } return 0; } static int usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) { channel_t chn; JSList *node; jack_default_audio_sample_t* buf[2]; snd_pcm_sframes_t nwritten; snd_pcm_uframes_t contiguous; snd_pcm_uframes_t offset; jack_port_t *port; int err; snd_pcm_uframes_t nframes_ = nframes; driver->process_count++; if (!driver->playback_handle || driver->engine->freewheeling) { return 0; } if (driver->midi) (driver->midi->write)(driver->midi, nframes); nwritten = 0; /* check current input monitor request status */ driver->input_monitor_mask = 0; for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { if (((jack_port_t *) node->data)->shared->monitor_requests) { driver->input_monitor_mask |= (1<hw_monitoring) { if ((driver->hw->input_monitor_mask != driver->input_monitor_mask) && !driver->all_monitor_in) { driver->hw->set_input_monitor_mask ( driver->hw, driver->input_monitor_mask); } } if (snd_pcm_mmap_begin(driver->playback_handle, &driver->playback_areas, &offset, &nframes_) < 0) { jack_error ("ALSA/USX2Y: %s: mmap areas info error", driver->alsa_name_capture); return -1; } for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) { port = (jack_port_t *) node->data; buf[chn] = jack_port_get_buffer (port, nframes_); } while (nframes) { contiguous = nframes; if (usx2y_driver_get_channel_addresses_playback ( driver, &contiguous) < 0) { return -1; } for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) { port = (jack_port_t *) node->data; alsa_driver_write_to_channel (driver, chn, buf[chn] + nwritten, contiguous); } nwritten += contiguous; nframes -= contiguous; } if ((err = snd_pcm_mmap_commit (driver->playback_handle, offset, nframes_)) < 0) { jack_error ("ALSA/USX2Y: could not complete playback of %" PRIu32 " frames: error = %d", nframes_, err); if (err != -EPIPE && err != -ESTRPIPE) return -1; } return 0; } static void usx2y_driver_setup (alsa_driver_t *driver) { driver->nt_start = (JackDriverNTStartFunction) usx2y_driver_start; driver->nt_stop = (JackDriverNTStopFunction) usx2y_driver_stop; driver->read = (JackDriverReadFunction) usx2y_driver_read; driver->write = (JackDriverReadFunction) usx2y_driver_write; driver->null_cycle = (JackDriverNullCycleFunction) usx2y_driver_null_cycle; } jack_hardware_t * jack_alsa_usx2y_hw_new (alsa_driver_t *driver) { jack_hardware_t *hw; usx2y_t *h; int hwdep_cardno; int hwdep_devno; char *hwdep_colon; char hwdep_name[9]; snd_hwdep_t *hwdep_handle; hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); hw->capabilities = 0; hw->input_monitor_mask = 0; hw->private_hw = 0; hw->set_input_monitor_mask = usx2y_set_input_monitor_mask; hw->change_sample_clock = usx2y_change_sample_clock; hw->release = usx2y_release; /* Derive the special USB US-X2Y hwdep pcm device name from * the playback one, thus allowing the use of the "rawusb" * experimental stuff if, and only if, the "hw:n,2" device * name is specified. Otherwise, fallback to generic backend. */ hwdep_handle = NULL; hwdep_cardno = hwdep_devno = 0; if ((hwdep_colon = strrchr(driver->alsa_name_playback, ':')) != NULL) sscanf(hwdep_colon, ":%d,%d", &hwdep_cardno, &hwdep_devno); if (hwdep_devno == 2) { snprintf(hwdep_name, sizeof(hwdep_name), "hw:%d,1", hwdep_cardno); if (snd_hwdep_open (&hwdep_handle, hwdep_name, O_RDWR) < 0) { jack_error ("ALSA/USX2Y: Cannot open hwdep device \"%s\"", hwdep_name); } else { /* Allocate specific USX2Y hwdep pcm struct. */ h = (usx2y_t *) malloc (sizeof (usx2y_t)); h->driver = driver; h->hwdep_handle = hwdep_handle; hw->private_hw = h; /* Set our own operational function pointers. */ usx2y_driver_setup(driver); jack_info("ALSA/USX2Y: EXPERIMENTAL hwdep pcm device %s" " (aka \"rawusb\")", driver->alsa_name_playback); } } return hw; } 1.9.12~dfsg/linux/alsa/alsa_midi_impl.h0000644000000000000000000000505613214314510016541 0ustar rootroot/* * Copyright (c) 2007 Dmitry S. Baikov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __jack_alsa_midi_impl_h__ #define __jack_alsa_midi_impl_h__ #include "JackConstants.h" #ifdef JACKMP #include "types.h" #ifdef __cplusplus extern "C" { #endif int JACK_is_realtime(jack_client_t *client); int JACK_client_create_thread(jack_client_t *client, pthread_t *thread, int priority, int realtime, void *(*start_routine)(void*), void *arg); jack_port_t* JACK_port_register(jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size); int JACK_port_unregister(jack_client_t *, jack_port_t*); void* JACK_port_get_buffer(jack_port_t*, jack_nframes_t); int JACK_port_set_alias(jack_port_t* port, const char* name); jack_nframes_t JACK_get_sample_rate(jack_client_t *); jack_nframes_t JACK_frame_time(jack_client_t *); jack_nframes_t JACK_last_frame_time(jack_client_t *); #define jack_is_realtime JACK_is_realtime #define jack_client_create_thread JACK_client_create_thread #define jack_port_register JACK_port_register #define jack_port_unregister JACK_port_unregister #define jack_port_get_buffer JACK_port_get_buffer #define jack_port_set_alias JACK_port_set_alias #define jack_get_sample_rate JACK_get_sample_rate #define jack_frame_time JACK_frame_time #define jack_last_frame_time JACK_last_frame_time #ifdef __cplusplus } // extern "C" #endif #else // usual jack #include "jack.h" #include "thread.h" #endif #if defined(STANDALONE) #define MESSAGE(...) fprintf(stderr, __VA_ARGS__) #elif !defined(JACKMP) #include #endif #define info_log(...) jack_info(__VA_ARGS__) #define error_log(...) jack_error(__VA_ARGS__) #ifdef ALSA_MIDI_DEBUG #define debug_log(...) jack_info(__VA_ARGS__) #else #define debug_log(...) #endif #include "alsa_midi.h" #endif /* __jack_alsa_midi_impl_h__ */ 1.9.12~dfsg/linux/alsa/alsa_seqmidi.c0000644000000000000000000005736013214314510016231 0ustar rootroot/* * ALSA SEQ < - > JACK MIDI bridge * * Copyright (c) 2006,2007 Dmitry S. Baikov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * alsa_seqmidi_read: * add new ports * reads queued snd_seq_event's * if PORT_EXIT: mark port as dead * if PORT_ADD, PORT_CHANGE: send addr to port_thread (it also may mark port as dead) * else process input event * remove dead ports and send them to port_thread * * alsa_seqmidi_write: * remove dead ports and send them to port_thread * add new ports * queue output events * * port_thread: * wait for port_sem * free deleted ports * create new ports or mark existing as dead */ #include #include #include #include #include #include #include #include #include "midiport.h" #include "ringbuffer.h" #include "alsa_midi_impl.h" #include "JackError.h" #define NSEC_PER_SEC ((int64_t)1000*1000*1000) enum { MAX_PORTS = 64, MAX_EVENT_SIZE = 1024, }; typedef struct port_t port_t; enum { PORT_HASH_BITS = 4, PORT_HASH_SIZE = 1 << PORT_HASH_BITS }; typedef port_t* port_hash_t[PORT_HASH_SIZE]; struct port_t { port_t *next; int is_dead; char name[64]; snd_seq_addr_t remote; jack_port_t *jack_port; jack_ringbuffer_t *early_events; // alsa_midi_event_t + data int64_t last_out_time; void *jack_buf; }; typedef struct { snd_midi_event_t *codec; jack_ringbuffer_t *new_ports; port_t *ports[MAX_PORTS]; } stream_t; typedef struct alsa_seqmidi { alsa_midi_t ops; jack_client_t *jack; snd_seq_t *seq; int client_id; int port_id; int queue; int keep_walking; pthread_t port_thread; sem_t port_sem; jack_ringbuffer_t *port_add; // snd_seq_addr_t jack_ringbuffer_t *port_del; // port_t* stream_t stream[2]; char alsa_name[32]; int midi_in_cnt; int midi_out_cnt; } alsa_seqmidi_t; struct alsa_midi_event { int64_t time; int size; }; typedef struct alsa_midi_event alsa_midi_event_t; struct process_info { int dir; jack_nframes_t nframes; jack_nframes_t period_start; jack_nframes_t sample_rate; jack_nframes_t cur_frames; int64_t alsa_time; }; enum PortType { PORT_INPUT = 0, PORT_OUTPUT = 1 }; typedef void (*port_jack_func)(alsa_seqmidi_t *self, port_t *port,struct process_info* info); static void do_jack_input(alsa_seqmidi_t *self, port_t *port, struct process_info* info); static void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* info); typedef struct { int alsa_mask; int jack_caps; char name[9]; port_jack_func jack_func; } port_type_t; static port_type_t port_type[2] = { { SND_SEQ_PORT_CAP_SUBS_READ, JackPortIsOutput, "playback", do_jack_input }, { SND_SEQ_PORT_CAP_SUBS_WRITE, JackPortIsInput, "capture", do_jack_output } }; static void alsa_seqmidi_delete(alsa_midi_t *m); static int alsa_seqmidi_attach(alsa_midi_t *m); static int alsa_seqmidi_detach(alsa_midi_t *m); static int alsa_seqmidi_start(alsa_midi_t *m); static int alsa_seqmidi_stop(alsa_midi_t *m); static void alsa_seqmidi_read(alsa_midi_t *m, jack_nframes_t nframes); static void alsa_seqmidi_write(alsa_midi_t *m, jack_nframes_t nframes); static void stream_init(alsa_seqmidi_t *self, int dir) { stream_t *str = &self->stream[dir]; str->new_ports = jack_ringbuffer_create(MAX_PORTS*sizeof(port_t*)); snd_midi_event_new(MAX_EVENT_SIZE, &str->codec); } static void port_free(alsa_seqmidi_t *self, port_t *port); static void free_ports(alsa_seqmidi_t *self, jack_ringbuffer_t *ports); static void stream_attach(alsa_seqmidi_t *self, int dir) { } static void stream_detach(alsa_seqmidi_t *self, int dir) { stream_t *str = &self->stream[dir]; int i; free_ports(self, str->new_ports); // delete all ports from hash for (i=0; iports[i]; while (port) { port_t *next = port->next; port_free(self, port); port = next; } str->ports[i] = NULL; } } static void stream_close(alsa_seqmidi_t *self, int dir) { stream_t *str = &self->stream[dir]; if (str->codec) snd_midi_event_free(str->codec); if (str->new_ports) jack_ringbuffer_free(str->new_ports); } alsa_midi_t* alsa_seqmidi_new(jack_client_t *client, const char* alsa_name) { alsa_seqmidi_t *self = calloc(1, sizeof(alsa_seqmidi_t)); debug_log("midi: new"); if (!self) return NULL; self->jack = client; if (!alsa_name) alsa_name = "jack_midi"; snprintf(self->alsa_name, sizeof(self->alsa_name), "%s", alsa_name); self->port_add = jack_ringbuffer_create(2*MAX_PORTS*sizeof(snd_seq_addr_t)); self->port_del = jack_ringbuffer_create(2*MAX_PORTS*sizeof(port_t*)); sem_init(&self->port_sem, 0, 0); stream_init(self, PORT_INPUT); stream_init(self, PORT_OUTPUT); self->midi_in_cnt = 0; self->midi_out_cnt = 0; self->ops.destroy = alsa_seqmidi_delete; self->ops.attach = alsa_seqmidi_attach; self->ops.detach = alsa_seqmidi_detach; self->ops.start = alsa_seqmidi_start; self->ops.stop = alsa_seqmidi_stop; self->ops.read = alsa_seqmidi_read; self->ops.write = alsa_seqmidi_write; return &self->ops; } static void alsa_seqmidi_delete(alsa_midi_t *m) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; debug_log("midi: delete"); alsa_seqmidi_detach(m); stream_close(self, PORT_OUTPUT); stream_close(self, PORT_INPUT); jack_ringbuffer_free(self->port_add); jack_ringbuffer_free(self->port_del); sem_close(&self->port_sem); free(self); } static int alsa_seqmidi_attach(alsa_midi_t *m) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; int err; debug_log("midi: attach"); if (self->seq) return -EALREADY; if ((err = snd_seq_open(&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) { error_log("failed to open alsa seq"); return err; } snd_seq_set_client_name(self->seq, self->alsa_name); self->port_id = snd_seq_create_simple_port(self->seq, "port", SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_WRITE #ifndef JACK_MIDI_DEBUG |SND_SEQ_PORT_CAP_NO_EXPORT #endif ,SND_SEQ_PORT_TYPE_APPLICATION); self->client_id = snd_seq_client_id(self->seq); self->queue = snd_seq_alloc_queue(self->seq); snd_seq_start_queue(self->seq, self->queue, 0); stream_attach(self, PORT_INPUT); stream_attach(self, PORT_OUTPUT); snd_seq_nonblock(self->seq, 1); return 0; } static int alsa_seqmidi_detach(alsa_midi_t *m) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; debug_log("midi: detach"); if (!self->seq) return -EALREADY; alsa_seqmidi_stop(m); jack_ringbuffer_reset(self->port_add); free_ports(self, self->port_del); stream_detach(self, PORT_INPUT); stream_detach(self, PORT_OUTPUT); snd_seq_close(self->seq); self->seq = NULL; return 0; } static void* port_thread(void *); static void add_existing_ports(alsa_seqmidi_t *self); static void update_ports(alsa_seqmidi_t *self); static void add_ports(stream_t *str); static int alsa_seqmidi_start(alsa_midi_t *m) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; int err; debug_log("midi: start"); if (!self->seq) return -EBADF; if (self->keep_walking) return -EALREADY; snd_seq_connect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); snd_seq_drop_input(self->seq); add_existing_ports(self); update_ports(self); add_ports(&self->stream[PORT_INPUT]); add_ports(&self->stream[PORT_OUTPUT]); self->keep_walking = 1; if ((err = pthread_create(&self->port_thread, NULL, port_thread, self))) { self->keep_walking = 0; return -errno; } return 0; } static int alsa_seqmidi_stop(alsa_midi_t *m) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; debug_log("midi: stop"); if (!self->keep_walking) return -EALREADY; snd_seq_disconnect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); self->keep_walking = 0; sem_post(&self->port_sem); pthread_join(self->port_thread, NULL); self->port_thread = 0; return 0; } static int alsa_connect_from(alsa_seqmidi_t *self, int client, int port) { snd_seq_port_subscribe_t* sub; snd_seq_addr_t seq_addr; int err; snd_seq_port_subscribe_alloca(&sub); seq_addr.client = client; seq_addr.port = port; snd_seq_port_subscribe_set_sender(sub, &seq_addr); seq_addr.client = self->client_id; seq_addr.port = self->port_id; snd_seq_port_subscribe_set_dest(sub, &seq_addr); snd_seq_port_subscribe_set_time_update(sub, 1); snd_seq_port_subscribe_set_queue(sub, self->queue); snd_seq_port_subscribe_set_time_real(sub, 1); if ((err=snd_seq_subscribe_port(self->seq, sub))) error_log("can't subscribe to %d:%d - %s", client, port, snd_strerror(err)); return err; } /* * ==================== Port routines ============================= */ static inline int port_hash(snd_seq_addr_t addr) { return (addr.client + addr.port) % PORT_HASH_SIZE; } static port_t* port_get(port_hash_t hash, snd_seq_addr_t addr) { port_t **pport = &hash[port_hash(addr)]; while (*pport) { port_t *port = *pport; if (port->remote.client == addr.client && port->remote.port == addr.port) return port; pport = &port->next; } return NULL; } static void port_insert(port_hash_t hash, port_t *port) { port_t **pport = &hash[port_hash(port->remote)]; port->next = *pport; *pport = port; } static void port_setdead(port_hash_t hash, snd_seq_addr_t addr) { port_t *port = port_get(hash, addr); if (port) port->is_dead = 1; // see jack_process else { debug_log("port_setdead: not found (%d:%d)", addr.client, addr.port); } } static void port_free(alsa_seqmidi_t *self, port_t *port) { //snd_seq_disconnect_from(self->seq, self->port_id, port->remote.client, port->remote.port); //snd_seq_disconnect_to(self->seq, self->port_id, port->remote.client, port->remote.port); if (port->early_events) jack_ringbuffer_free(port->early_events); if (port->jack_port) jack_port_unregister(self->jack, port->jack_port); info_log("port deleted: %s", port->name); free(port); } static port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const snd_seq_port_info_t *info) { snd_seq_client_info_t* client_info; port_t *port; char *c; int err; int jack_caps; char name[128]; port = calloc(1, sizeof(port_t)); if (!port) return NULL; port->remote = addr; snd_seq_client_info_alloca (&client_info); snd_seq_get_any_client_info (self->seq, addr.client, client_info); snprintf(port->name, sizeof(port->name), "alsa_pcm:%s/midi_%s_%d", snd_seq_client_info_get_name(client_info), port_type[type].name, addr.port+1); // replace all offending characters by - for (c = port->name; *c; ++c) if (!isalnum(*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') *c = '-'; jack_caps = port_type[type].jack_caps; /* mark anything that looks like a hardware port as physical&terminal */ if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE|SND_SEQ_PORT_TYPE_PORT|SND_SEQ_PORT_TYPE_SPECIFIC)) { jack_caps |= (JackPortIsPhysical | JackPortIsTerminal); } if (jack_caps & JackPortIsOutput) snprintf(name, sizeof(name), "system:midi_capture_%d", ++self->midi_in_cnt); else snprintf(name, sizeof(name), "system:midi_playback_%d", ++self->midi_out_cnt); port->jack_port = jack_port_register(self->jack, name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0); if (!port->jack_port) goto failed; jack_port_set_alias (port->jack_port, port->name); /* generate an alias */ snprintf(port->name, sizeof(port->name), "%s:midi/%s_%d", snd_seq_client_info_get_name (client_info), port_type[type].name, addr.port+1); // replace all offending characters by - for (c = port->name; *c; ++c) if (!isalnum(*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') *c = '-'; jack_port_set_alias (port->jack_port, port->name); if (type == PORT_INPUT) err = alsa_connect_from(self, port->remote.client, port->remote.port); else err = snd_seq_connect_to(self->seq, self->port_id, port->remote.client, port->remote.port); if (err) goto failed; port->early_events = jack_ringbuffer_create(MAX_EVENT_SIZE*16); info_log("port created: %s", port->name); return port; failed: port_free(self, port); return NULL; } /* * ==================== Port add/del handling thread ============================== */ static void update_port_type(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, int caps, const snd_seq_port_info_t *info) { stream_t *str = &self->stream[type]; int alsa_mask = port_type[type].alsa_mask; port_t *port = port_get(str->ports, addr); debug_log("update_port_type(%d:%d)", addr.client, addr.port); if (port && (caps & alsa_mask)!=alsa_mask) { debug_log("setdead: %s", port->name); port->is_dead = 1; } if (!port && (caps & alsa_mask)==alsa_mask) { assert (jack_ringbuffer_write_space(str->new_ports) >= sizeof(port)); port = port_create(self, type, addr, info); if (port) jack_ringbuffer_write(str->new_ports, (char*)&port, sizeof(port)); } } static void update_port(alsa_seqmidi_t *self, snd_seq_addr_t addr, const snd_seq_port_info_t *info) { unsigned int port_caps = snd_seq_port_info_get_capability(info); if (port_caps & SND_SEQ_PORT_CAP_NO_EXPORT) return; update_port_type(self, PORT_INPUT, addr, port_caps, info); update_port_type(self, PORT_OUTPUT,addr, port_caps, info); } static void free_ports(alsa_seqmidi_t *self, jack_ringbuffer_t *ports) { port_t *port; int sz; while ((sz = jack_ringbuffer_read(ports, (char*)&port, sizeof(port)))) { assert (sz == sizeof(port)); port_free(self, port); } } static void update_ports(alsa_seqmidi_t *self) { snd_seq_addr_t addr; snd_seq_port_info_t *info; int size; snd_seq_port_info_alloca(&info); while ((size = jack_ringbuffer_read(self->port_add, (char*)&addr, sizeof(addr)))) { int err; assert (size == sizeof(addr)); assert (addr.client != self->client_id); if ((err=snd_seq_get_any_port_info(self->seq, addr.client, addr.port, info))>=0) { update_port(self, addr, info); } else { //port_setdead(self->stream[PORT_INPUT].ports, addr); //port_setdead(self->stream[PORT_OUTPUT].ports, addr); } } } static void* port_thread(void *arg) { alsa_seqmidi_t *self = arg; while (self->keep_walking) { sem_wait(&self->port_sem); free_ports(self, self->port_del); update_ports(self); } debug_log("port_thread exited"); return NULL; } static void add_existing_ports(alsa_seqmidi_t *self) { snd_seq_addr_t addr; snd_seq_client_info_t *client_info; snd_seq_port_info_t *port_info; snd_seq_client_info_alloca(&client_info); snd_seq_port_info_alloca(&port_info); snd_seq_client_info_set_client(client_info, -1); while (snd_seq_query_next_client(self->seq, client_info) >= 0) { addr.client = snd_seq_client_info_get_client(client_info); if (addr.client == SND_SEQ_CLIENT_SYSTEM || addr.client == self->client_id) continue; snd_seq_port_info_set_client(port_info, addr.client); snd_seq_port_info_set_port(port_info, -1); while (snd_seq_query_next_port(self->seq, port_info) >= 0) { addr.port = snd_seq_port_info_get_port(port_info); update_port(self, addr, port_info); } } } /* * =================== Input/output port handling ========================= */ static void set_process_info(struct process_info *info, alsa_seqmidi_t *self, int dir, jack_nframes_t nframes) { const snd_seq_real_time_t* alsa_time; snd_seq_queue_status_t *status; snd_seq_queue_status_alloca(&status); info->dir = dir; info->period_start = jack_last_frame_time(self->jack); info->nframes = nframes; info->sample_rate = jack_get_sample_rate(self->jack); info->cur_frames = jack_frame_time(self->jack); // immediately get alsa'a real time (uhh, why everybody has their own 'real' time) snd_seq_get_queue_status(self->seq, self->queue, status); alsa_time = snd_seq_queue_status_get_real_time(status); info->alsa_time = alsa_time->tv_sec * NSEC_PER_SEC + alsa_time->tv_nsec; if (info->period_start + info->nframes < info->cur_frames) { int periods_lost = (info->cur_frames - info->period_start) / info->nframes; info->period_start += periods_lost * info->nframes; debug_log("xrun detected: %d periods lost\n", periods_lost); } } static void add_ports(stream_t *str) { port_t *port; while (jack_ringbuffer_read(str->new_ports, (char*)&port, sizeof(port))) { debug_log("jack: inserted port %s\n", port->name); port_insert(str->ports, port); } } static void jack_process(alsa_seqmidi_t *self, struct process_info *info) { stream_t *str = &self->stream[info->dir]; port_jack_func process = port_type[info->dir].jack_func; int i, del=0; add_ports(str); // process ports for (i=0; iports[i]; while (*pport) { port_t *port = *pport; port->jack_buf = jack_port_get_buffer(port->jack_port, info->nframes); if (info->dir == PORT_INPUT) jack_midi_clear_buffer(port->jack_buf); if (!port->is_dead) (*process)(self, port, info); else if (jack_ringbuffer_write_space(self->port_del) >= sizeof(port)) { debug_log("jack: removed port %s", port->name); *pport = port->next; jack_ringbuffer_write(self->port_del, (char*)&port, sizeof(port)); del++; continue; } pport = &port->next; } } if (del) sem_post(&self->port_sem); } /* * ============================ Input ============================== */ static void do_jack_input(alsa_seqmidi_t *self, port_t *port, struct process_info *info) { // process port->early_events alsa_midi_event_t ev; while (jack_ringbuffer_read(port->early_events, (char*)&ev, sizeof(ev))) { jack_midi_data_t* buf; int64_t time = ev.time - info->period_start; if (time < 0) time = 0; else if (time >= info->nframes) time = info->nframes - 1; buf = jack_midi_event_reserve(port->jack_buf, (jack_nframes_t)time, ev.size); if (buf) jack_ringbuffer_read(port->early_events, (char*)buf, ev.size); else jack_ringbuffer_read_advance(port->early_events, ev.size); debug_log("input: it's time for %d bytes at %lld", ev.size, time); } } static void port_event(alsa_seqmidi_t *self, snd_seq_event_t *ev) { const snd_seq_addr_t addr = ev->data.addr; if (addr.client == self->client_id) return; if (ev->type == SND_SEQ_EVENT_PORT_START || ev->type == SND_SEQ_EVENT_PORT_CHANGE) { assert (jack_ringbuffer_write_space(self->port_add) >= sizeof(addr)); debug_log("port_event: add/change %d:%d", addr.client, addr.port); jack_ringbuffer_write(self->port_add, (char*)&addr, sizeof(addr)); sem_post(&self->port_sem); } else if (ev->type == SND_SEQ_EVENT_PORT_EXIT) { debug_log("port_event: del %d:%d", addr.client, addr.port); port_setdead(self->stream[PORT_INPUT].ports, addr); port_setdead(self->stream[PORT_OUTPUT].ports, addr); } } static void input_event(alsa_seqmidi_t *self, snd_seq_event_t *alsa_event, struct process_info* info) { jack_midi_data_t data[MAX_EVENT_SIZE]; stream_t *str = &self->stream[PORT_INPUT]; long size; int64_t alsa_time, time_offset; int64_t frame_offset, event_frame; port_t *port; port = port_get(str->ports, alsa_event->source); if (!port) return; /* * RPNs, NRPNs, Bank Change, etc. need special handling * but seems, ALSA does it for us already. */ snd_midi_event_reset_decode(str->codec); if ((size = snd_midi_event_decode(str->codec, data, sizeof(data), alsa_event))<0) return; // fixup NoteOn with vel 0 if ((data[0] & 0xF0) == 0x90 && data[2] == 0x00) { data[0] = 0x80 + (data[0] & 0x0F); data[2] = 0x40; } alsa_time = alsa_event->time.time.tv_sec * NSEC_PER_SEC + alsa_event->time.time.tv_nsec; time_offset = info->alsa_time - alsa_time; frame_offset = (info->sample_rate * time_offset) / NSEC_PER_SEC; event_frame = (int64_t)info->cur_frames - info->period_start - frame_offset + info->nframes; debug_log("input: %d bytes at event_frame = %d", (int)size, (int)event_frame); if (event_frame >= info->nframes && jack_ringbuffer_write_space(port->early_events) >= (sizeof(alsa_midi_event_t) + size)) { alsa_midi_event_t ev; ev.time = event_frame + info->period_start; ev.size = size; jack_ringbuffer_write(port->early_events, (char*)&ev, sizeof(ev)); jack_ringbuffer_write(port->early_events, (char*)data, size); debug_log("postponed to next frame +%d", (int) (event_frame - info->nframes)); return; } if (event_frame < 0) event_frame = 0; else if (event_frame >= info->nframes) event_frame = info->nframes - 1; jack_midi_event_write(port->jack_buf, event_frame, data, size); } static void alsa_seqmidi_read(alsa_midi_t *m, jack_nframes_t nframes) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; int res; snd_seq_event_t *event; struct process_info info; if (!self->keep_walking) return; set_process_info(&info, self, PORT_INPUT, nframes); jack_process(self, &info); while ((res = snd_seq_event_input(self->seq, &event))>0) { if (event->source.client == SND_SEQ_CLIENT_SYSTEM) port_event(self, event); else input_event(self, event, &info); } } /* * ============================ Output ============================== */ static void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* info) { stream_t *str = &self->stream[info->dir]; int nevents = jack_midi_get_event_count(port->jack_buf); int i; for (i=0; ijack_buf, i); snd_seq_ev_clear(&alsa_event); snd_midi_event_reset_encode(str->codec); if (!snd_midi_event_encode(str->codec, jack_event.buffer, jack_event.size, &alsa_event)) continue; // invalid event snd_seq_ev_set_source(&alsa_event, self->port_id); snd_seq_ev_set_dest(&alsa_event, port->remote.client, port->remote.port); /* NOTE: in case of xrun it could become negative, so it is essential to use signed type! */ frame_offset = (int64_t)jack_event.time + info->period_start + info->nframes - info->cur_frames; if (frame_offset < 0) { frame_offset = info->nframes + jack_event.time; error_log("internal xrun detected: frame_offset = %"PRId64"\n", frame_offset); } /* Ken Ellinwood reported problems with this assert. * Seems, magic 2 should be replaced with nperiods. */ //FIXME: assert (frame_offset < info->nframes*2); //if (frame_offset < info->nframes * info->nperiods) // debug_log("alsa_out: BLAH-BLAH-BLAH"); out_time = info->alsa_time + (frame_offset * NSEC_PER_SEC) / info->sample_rate; debug_log("alsa_out: frame_offset = %lld, info->alsa_time = %lld, out_time = %lld, port->last_out_time = %lld", frame_offset, info->alsa_time, out_time, port->last_out_time); // we should use absolute time to prevent reordering caused by rounding errors if (out_time < port->last_out_time) { debug_log("alsa_out: limiting out_time %lld at %lld", out_time, port->last_out_time); out_time = port->last_out_time; } else port->last_out_time = out_time; out_rt.tv_nsec = out_time % NSEC_PER_SEC; out_rt.tv_sec = out_time / NSEC_PER_SEC; snd_seq_ev_schedule_real(&alsa_event, self->queue, 0, &out_rt); err = snd_seq_event_output(self->seq, &alsa_event); debug_log("alsa_out: written %d bytes to %s at %+d (%lld): %d", (int)jack_event.size, port->name, (int)frame_offset, out_time, err); } } static void alsa_seqmidi_write(alsa_midi_t *m, jack_nframes_t nframes) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; struct process_info info; if (!self->keep_walking) return; set_process_info(&info, self, PORT_OUTPUT, nframes); jack_process(self, &info); snd_seq_drain_output(self->seq); } 1.9.12~dfsg/linux/alsa/jslist.h0000644000000000000000000001261513214314510015105 0ustar rootroot/* Based on gslist.c from glib-1.2.9 (LGPL). Adaption to JACK, Copyright (C) 2002 Kai Vehmanen. - replaced use of gtypes with normal ANSI C types - glib's memery allocation routines replaced with malloc/free calls This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: jslist.h,v 1.2 2005/11/23 11:24:29 letz Exp $ */ #ifndef __jack_jslist_h__ #define __jack_jslist_h__ #include typedef struct _JSList JSList; typedef int (*JCompareFunc) (void* a, void* b); struct _JSList { void *data; JSList *next; }; static __inline__ JSList* jack_slist_alloc (void) { JSList *new_list; new_list = (JSList*)malloc(sizeof(JSList)); new_list->data = NULL; new_list->next = NULL; return new_list; } static __inline__ JSList* jack_slist_prepend (JSList *list, void *data) { JSList *new_list; new_list = (JSList*)malloc(sizeof(JSList)); new_list->data = data; new_list->next = list; return new_list; } #define jack_slist_next(slist) ((slist) ? (((JSList *)(slist))->next) : NULL) static __inline__ JSList* jack_slist_last (JSList *list) { if (list) { while (list->next) list = list->next; } return list; } static __inline__ JSList* jack_slist_remove_link (JSList *list, JSList *link) { JSList *tmp; JSList *prev; prev = NULL; tmp = list; while (tmp) { if (tmp == link) { if (prev) prev->next = tmp->next; if (list == tmp) list = list->next; tmp->next = NULL; break; } prev = tmp; tmp = tmp->next; } return list; } static __inline__ void jack_slist_free (JSList *list) { while (list) { JSList *next = list->next; free(list); list = next; } } static __inline__ void jack_slist_free_1 (JSList *list) { if (list) { free(list); } } static __inline__ JSList* jack_slist_remove (JSList *list, void *data) { JSList *tmp; JSList *prev; prev = NULL; tmp = list; while (tmp) { if (tmp->data == data) { if (prev) prev->next = tmp->next; if (list == tmp) list = list->next; tmp->next = NULL; jack_slist_free (tmp); break; } prev = tmp; tmp = tmp->next; } return list; } static __inline__ unsigned int jack_slist_length (JSList *list) { unsigned int length; length = 0; while (list) { length++; list = list->next; } return length; } static __inline__ JSList* jack_slist_find (JSList *list, void *data) { while (list) { if (list->data == data) break; list = list->next; } return list; } static __inline__ JSList* jack_slist_copy (JSList *list) { JSList *new_list = NULL; if (list) { JSList *last; new_list = jack_slist_alloc (); new_list->data = list->data; last = new_list; list = list->next; while (list) { last->next = jack_slist_alloc (); last = last->next; last->data = list->data; list = list->next; } } return new_list; } static __inline__ JSList* jack_slist_append (JSList *list, void *data) { JSList *new_list; JSList *last; new_list = jack_slist_alloc (); new_list->data = data; if (list) { last = jack_slist_last (list); last->next = new_list; return list; } else return new_list; } static __inline__ JSList* jack_slist_sort_merge (JSList *l1, JSList *l2, JCompareFunc compare_func) { JSList list, *l; l = &list; while (l1 && l2) { if (compare_func(l1->data, l2->data) < 0) { l = l->next = l1; l1 = l1->next; } else { l = l->next = l2; l2 = l2->next; } } l->next = l1 ? l1 : l2; return list.next; } static __inline__ JSList* jack_slist_sort (JSList *list, JCompareFunc compare_func) { JSList *l1, *l2; if (!list) return NULL; if (!list->next) return list; l1 = list; l2 = list->next; while ((l2 = l2->next) != NULL) { if ((l2 = l2->next) == NULL) break; l1 = l1->next; } l2 = l1->next; l1->next = NULL; return jack_slist_sort_merge (jack_slist_sort (list, compare_func), jack_slist_sort (l2, compare_func), compare_func); } #endif /* __jack_jslist_h__ */ 1.9.12~dfsg/linux/alsa/JackAlsaAdapter.cpp0000644000000000000000000001766513214314510017114 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #if defined(HAVE_CONFIG_H) #include "config.h" #endif #include "JackAlsaAdapter.h" #include "JackGlobals.h" #include "JackEngineControl.h" namespace Jack { JackAlsaAdapter::JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ) : JackAudioAdapterInterface ( buffer_size, sample_rate ), fThread ( this ), fAudioInterface ( buffer_size, sample_rate ) { const JSList* node; const jack_driver_param_t* param; fCaptureChannels = 2; fPlaybackChannels = 2; fAudioInterface.fPeriod = 2; for ( node = params; node; node = jack_slist_next ( node ) ) { param = ( const jack_driver_param_t* ) node->data; switch ( param->character ) { case 'i': fCaptureChannels = param->value.ui; break; case 'o': fPlaybackChannels = param->value.ui; break; case 'C': if (strncmp(param->value.str,"none",4) != 0) { fAudioInterface.fCaptureName = strdup ( param->value.str ); } break; case 'P': if (strncmp(param->value.str,"none",4) != 0) { fAudioInterface.fPlaybackName = strdup ( param->value.str ); } break; case 'D': break; case 'n': fAudioInterface.fPeriod = param->value.ui; break; case 'd': fAudioInterface.fCardName = strdup ( param->value.str ); break; case 'r': fAudioInterface.fFrequency = param->value.ui; SetAdaptedSampleRate ( param->value.ui ); break; case 'p': fAudioInterface.fBuffering = param->value.ui; SetAdaptedBufferSize ( param->value.ui ); break; case 'q': fQuality = param->value.ui; break; case 'g': fRingbufferCurSize = param->value.ui; fAdaptative = false; break; } } fAudioInterface.setInputs ( fCaptureChannels ); fAudioInterface.setOutputs ( fPlaybackChannels ); } int JackAlsaAdapter::Open() { //open audio interface if ( fAudioInterface.open() ) return -1; //start adapter thread if ( fThread.StartSync() < 0 ) { jack_error ( "Cannot start audioadapter thread" ); return -1; } //display card info fAudioInterface.longinfo(); //turn the thread realtime fThread.AcquireRealTime(GetEngineControl()->fClientPriority); return 0; } int JackAlsaAdapter::Close() { #ifdef JACK_MONITOR fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif switch ( fThread.GetStatus() ) { // Kill the thread in Init phase case JackThread::kStarting: case JackThread::kIniting: if ( fThread.Kill() < 0 ) { jack_error ( "Cannot kill thread" ); return -1; } break; // Stop when the thread cycle is finished case JackThread::kRunning: if ( fThread.Stop() < 0 ) { jack_error ( "Cannot stop thread" ); return -1; } break; default: break; } return fAudioInterface.close(); } bool JackAlsaAdapter::Init() { //fill the hardware buffers for ( unsigned int i = 0; i < fAudioInterface.fPeriod; i++ ) fAudioInterface.write(); return true; } bool JackAlsaAdapter::Execute() { //read data from audio interface if (fAudioInterface.read() < 0) return false; PushAndPull(fAudioInterface.fInputSoftChannels, fAudioInterface.fOutputSoftChannels, fAdaptedBufferSize); //write data to audio interface if (fAudioInterface.write() < 0) return false; return true; } int JackAlsaAdapter::SetSampleRate ( jack_nframes_t sample_rate ) { JackAudioAdapterInterface::SetHostSampleRate ( sample_rate ); Close(); return Open(); } int JackAlsaAdapter::SetBufferSize ( jack_nframes_t buffer_size ) { JackAudioAdapterInterface::SetHostBufferSize ( buffer_size ); Close(); return Open(); } } // namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler); strcpy(value.str, "none"); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set device", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Provide playback ports. Optionally set device", NULL); strcpy(value.str, "hw:0"); jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "ALSA device name", NULL); value.ui = 48000U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = 512U; jack_driver_descriptor_add_parameter(desc, &filler, "periodsize", 'p', JackDriverParamUInt, &value, NULL, "Period size", NULL); value.ui = 2U; jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods of playback latency", NULL); value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Number of capture channels (defaults to hardware max)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Number of playback channels (defaults to hardware max)", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamUInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL); value.ui = 32768; jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamUInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)"); return desc; } #ifdef __cplusplus } #endif 1.9.12~dfsg/linux/alsa/midi_pack.h0000644000000000000000000000260213214314510015510 0ustar rootroot/* * Copyright (c) 2006,2007 Dmitry S. Baikov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __jack_midi_pack_h__ #define __jack_midi_pack_h__ typedef struct { int running_status; } midi_pack_t; static inline void midi_pack_reset(midi_pack_t *p) { p->running_status = 0; } static void midi_pack_event(midi_pack_t *p, jack_midi_event_t *e) { if (e->buffer[0] >= 0x80 && e->buffer[0] < 0xF0) { // Voice Message if (e->buffer[0] == p->running_status) { e->buffer++; e->size--; } else p->running_status = e->buffer[0]; } else if (e->buffer[0] < 0xF8) { // not System Realtime p->running_status = 0; } } #endif /* __jack_midi_pack_h__ */ 1.9.12~dfsg/linux/firewire/0000755000000000000000000000000013214314510014313 5ustar rootroot1.9.12~dfsg/linux/firewire/JackFFADOMidiOutputPort.cpp0000644000000000000000000000717213214314510021327 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "JackFFADOMidiOutputPort.h" #include "JackMidiUtil.h" #include "JackError.h" using Jack::JackFFADOMidiOutputPort; JackFFADOMidiOutputPort::JackFFADOMidiOutputPort(size_t non_rt_size, size_t max_non_rt_messages, size_t max_rt_messages) { event = 0; read_queue = new JackMidiBufferReadQueue(); std::auto_ptr read_queue_ptr(read_queue); send_queue = new JackFFADOMidiSendQueue(); std::auto_ptr send_queue_ptr(send_queue); raw_queue = new JackMidiRawOutputWriteQueue(send_queue, non_rt_size, max_non_rt_messages, max_rt_messages); send_queue_ptr.release(); read_queue_ptr.release(); } JackFFADOMidiOutputPort::~JackFFADOMidiOutputPort() { delete raw_queue; delete read_queue; delete send_queue; } void JackFFADOMidiOutputPort::Process(JackMidiBuffer *port_buffer, uint32_t *output_buffer, jack_nframes_t frames) { read_queue->ResetMidiBuffer(port_buffer); send_queue->ResetOutputBuffer(output_buffer, frames); jack_nframes_t boundary_frame = GetLastFrame() + frames; if (! event) { event = read_queue->DequeueEvent(); } for (; event; event = read_queue->DequeueEvent()) { switch (raw_queue->EnqueueEvent(event)) { case JackMidiWriteQueue::BUFFER_FULL: // Processing events early might free up some space in the raw // output queue. raw_queue->Process(boundary_frame); switch (raw_queue->EnqueueEvent(event)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: // This shouldn't really happen. It indicates a bug if it // does. jack_error("JackFFADOMidiOutputPort::Process - **BUG** " "JackMidiRawOutputWriteQueue::EnqueueEvent " "returned `BUFFER_FULL`, and then returned " "`BUFFER_TOO_SMALL` after a `Process()` call."); // Fallthrough on purpose case JackMidiWriteQueue::OK: continue; default: return; } case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackFFADOMidiOutputPort::Process - The write queue " "couldn't enqueue a %d-byte event. Dropping event.", event->size); // Fallthrough on purpose case JackMidiWriteQueue::OK: continue; default: // This is here to stop compliers from warning us about not // handling enumeration values. ; } break; } raw_queue->Process(boundary_frame); } 1.9.12~dfsg/linux/firewire/JackFFADOMidiSendQueue.cpp0000644000000000000000000000352213214314510021053 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "JackFFADOMidiSendQueue.h" #include "JackMidiUtil.h" using Jack::JackFFADOMidiSendQueue; JackFFADOMidiSendQueue::JackFFADOMidiSendQueue() { // Empty } Jack::JackMidiWriteQueue::EnqueueResult JackFFADOMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) { assert(size == 1); jack_nframes_t relative_time = (time < last_frame) ? 0 : time - last_frame; if (index < relative_time) { index = (relative_time % 8) ? (relative_time & (~ ((jack_nframes_t) 7))) + 8 : relative_time; } if (index >= length) { return BUFFER_FULL; } output_buffer[index] = 0x01000000 | ((uint32_t) *buffer); index += 8; return OK; } jack_nframes_t JackFFADOMidiSendQueue::GetNextScheduleFrame() { return last_frame + index; } void JackFFADOMidiSendQueue::ResetOutputBuffer(uint32_t *output_buffer, jack_nframes_t length) { index = 0; last_frame = GetLastFrame(); this->length = length; this->output_buffer = output_buffer; } 1.9.12~dfsg/linux/firewire/JackFFADOMidiInputPort.h0000644000000000000000000000262013214314510020564 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackFFADOMidiInputPort__ #define __JackFFADOMidiInputPort__ #include "JackFFADOMidiReceiveQueue.h" #include "JackMidiBufferWriteQueue.h" #include "JackMidiRawInputWriteQueue.h" namespace Jack { class JackFFADOMidiInputPort { private: jack_midi_event_t *event; JackMidiRawInputWriteQueue *raw_queue; JackFFADOMidiReceiveQueue *receive_queue; JackMidiBufferWriteQueue *write_queue; public: JackFFADOMidiInputPort(size_t max_bytes=4096); ~JackFFADOMidiInputPort(); void Process(JackMidiBuffer *port_buffer, uint32_t *input_buffer, jack_nframes_t frames); }; } #endif 1.9.12~dfsg/linux/firewire/JackFFADODriver.h0000644000000000000000000000530513214314510017253 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Grame Copyright (C) 2007 Pieter Palmers Copyright (C) 2012 Adrian Knoth This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackFFADODriver__ #define __JackFFADODriver__ #include "JackAudioDriver.h" #include "JackThreadedDriver.h" #include "JackTime.h" #include "ffado_driver.h" namespace Jack { /*! \brief The FFADO driver. */ class JackFFADODriver : public JackAudioDriver { private: // enable verbose messages int g_verbose; jack_driver_t* fDriver; int ffado_driver_attach (ffado_driver_t *driver); int ffado_driver_detach (ffado_driver_t *driver); int ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes); int ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes); jack_nframes_t ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status, float *delayed_usecs); int ffado_driver_start (ffado_driver_t *driver); int ffado_driver_stop (ffado_driver_t *driver); int ffado_driver_restart (ffado_driver_t *driver); ffado_driver_t *ffado_driver_new (const char *name, ffado_jack_settings_t *params); void ffado_driver_delete (ffado_driver_t *driver); void jack_driver_init (jack_driver_t *driver); void jack_driver_nt_init (jack_driver_nt_t * driver); void UpdateLatencies(); public: JackFFADODriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias,engine, table) {} virtual ~JackFFADODriver() {} int Open(ffado_jack_settings_t *cmlparams); int Close(); int Attach(); int Detach(); int Start(); int Stop(); int Read(); int Write(); // BufferSize can be changed bool IsFixedBufferSize() { return false; } int SetBufferSize(jack_nframes_t nframes); }; } // end of namespace #endif 1.9.12~dfsg/linux/firewire/ffado_driver.h0000644000000000000000000001271113214314510017120 0ustar rootroot/* * FireWire Backend for Jack * using FFADO * FFADO = Firewire (pro-)audio for linux * * http://www.ffado.org * http://www.jackaudio.org * * Copyright (C) 2005-2007 Pieter Palmers * Copyright (C) 2009 Devin Anderson * * adapted for JackMP by Pieter Palmers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Main Jack driver entry routines * */ #ifndef __JACK_FFADO_DRIVER_H__ #define __JACK_FFADO_DRIVER_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include // debug print control flags #define DEBUG_LEVEL_BUFFERS (1<<0) #define DEBUG_LEVEL_HANDLERS (1<<1) #define DEBUG_LEVEL_XRUN_RECOVERY (1<<2) #define DEBUG_LEVEL_WAIT (1<<3) #define DEBUG_LEVEL_RUN_CYCLE (1<<8) #define DEBUG_LEVEL_PACKETCOUNTER (1<<16) #define DEBUG_LEVEL_STARTUP (1<<17) #define DEBUG_LEVEL_THREADS (1<<18) //#define DEBUG_ENABLED #ifdef DEBUG_ENABLED // default debug level #define DEBUG_LEVEL ( DEBUG_LEVEL_RUN_CYCLE | \ (DEBUG_LEVEL_XRUN_RECOVERY)| DEBUG_LEVEL_STARTUP | DEBUG_LEVEL_WAIT | DEBUG_LEVEL_PACKETCOUNTER) #warning Building debug build! #define printMessage(format, args...) jack_error( "firewire MSG: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) #define printError(format, args...) jack_error( "firewire ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) #define printEnter() jack_error( "FWDRV ENTERS: %s (%s)\n", __FUNCTION__, __FILE__) #define printExit() jack_error( "FWDRV EXITS: %s (%s)\n", __FUNCTION__, __FILE__) #define printEnter() #define printExit() #define debugError(format, args...) jack_error( "firewire ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) #define debugPrint(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error("DEBUG %s:%d (%s) :" format, __FILE__, __LINE__, __FUNCTION__, ##args ); #define debugPrintShort(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error( format,##args ); #define debugPrintWithTimeStamp(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error( "%16lu: "format, debugGetCurrentUTime(),##args ); #define SEGFAULT int *test=NULL; *test=1; #else #define DEBUG_LEVEL #define printMessage(format, args...) if(g_verbose) \ jack_error("firewire MSG: " format, ##args ) #define printError(format, args...) jack_error("firewire ERR: " format, ##args ) #define printEnter() #define printExit() #define debugError(format, args...) #define debugPrint(Level, format, args...) #define debugPrintShort(Level, format, args...) #define debugPrintWithTimeStamp(Level, format, args...) #endif // thread priority setup #define FFADO_RT_PRIORITY_PACKETIZER_RELATIVE 5 typedef struct _ffado_driver ffado_driver_t; /* * Jack Driver command line parameters */ typedef struct _ffado_jack_settings ffado_jack_settings_t; struct _ffado_jack_settings { int verbose_level; int period_size_set; jack_nframes_t period_size; int sample_rate_set; int sample_rate; int buffer_size_set; jack_nframes_t buffer_size; int playback_ports; int capture_ports; jack_nframes_t capture_frame_latency; jack_nframes_t playback_frame_latency; int slave_mode; int snoop_mode; char *device_info; }; typedef struct _ffado_capture_channel { ffado_streaming_stream_type stream_type; uint32_t *midi_buffer; void *midi_input; } ffado_capture_channel_t; typedef struct _ffado_playback_channel { ffado_streaming_stream_type stream_type; uint32_t *midi_buffer; void *midi_output; } ffado_playback_channel_t; /* * JACK driver structure */ struct _ffado_driver { JACK_DRIVER_NT_DECL; jack_nframes_t sample_rate; jack_nframes_t period_size; unsigned long wait_time; jack_time_t wait_last; jack_time_t wait_next; int wait_late; jack_client_t *client; int xrun_detected; int xrun_count; int process_count; /* settings from the command line */ ffado_jack_settings_t settings; /* the firewire virtual device */ ffado_device_t *dev; channel_t playback_nchannels; channel_t capture_nchannels; ffado_playback_channel_t *playback_channels; ffado_capture_channel_t *capture_channels; ffado_sample_t *nullbuffer; ffado_sample_t *scratchbuffer; jack_nframes_t playback_frame_latency; jack_nframes_t capture_frame_latency; ffado_device_info_t device_info; ffado_options_t device_options; }; #endif /* __JACK_FFADO_DRIVER_H__ */ 1.9.12~dfsg/linux/firewire/JackFFADOMidiOutputPort.h0000644000000000000000000000301313214314510020762 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackFFADOMidiOutputPort__ #define __JackFFADOMidiOutputPort__ #include "JackFFADOMidiSendQueue.h" #include "JackMidiBufferReadQueue.h" #include "JackMidiRawOutputWriteQueue.h" namespace Jack { class JackFFADOMidiOutputPort { private: jack_midi_event_t *event; JackMidiRawOutputWriteQueue *raw_queue; JackMidiBufferReadQueue *read_queue; JackFFADOMidiSendQueue *send_queue; public: JackFFADOMidiOutputPort(size_t non_rt_size=4096, size_t max_non_rt_messages=1024, size_t max_rt_messages=128); ~JackFFADOMidiOutputPort(); void Process(JackMidiBuffer *port_buffer, uint32_t *output_buffer, jack_nframes_t frames); }; } #endif 1.9.12~dfsg/linux/firewire/JackFFADODriver.cpp0000644000000000000000000011061613214314510017610 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Grame Copyright (C) 2007 Pieter Palmers Copyright (C) 2009 Devin Anderson Copyright (C) 2012 Jonathan Woithe, Adrian Knoth This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "JackFFADODriver.h" #include "JackFFADOMidiInputPort.h" #include "JackFFADOMidiOutputPort.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackPort.h" #include "JackGraphManager.h" #include "JackCompilerDeps.h" #include "JackLockedEngine.h" // FFADO_API_VERSION was first defined with API_VERSION 9, so all previous // headers do not provide this define. #ifndef FFADO_API_VERSION extern "C" int ffado_streaming_set_period_size(ffado_device_t *dev, unsigned int period) __attribute__((__weak__)); #endif namespace Jack { // Basic functionality requires API version 8. If version 9 or later // is present the buffers can be resized at runtime. #define FIREWIRE_REQUIRED_FFADO_API_VERSION 8 #define FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE 9 #define jack_get_microseconds GetMicroSeconds int JackFFADODriver::ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes) { channel_t chn; jack_default_audio_sample_t* buf = NULL; printEnter(); for (chn = 0; chn < driver->capture_nchannels; chn++) { // if nothing connected, don't process if (fGraphManager->GetConnectionsNum(fCapturePortList[chn]) == 0) { buf = (jack_default_audio_sample_t*)driver->scratchbuffer; // we always have to specify a valid buffer ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(buf)); // notify the streaming system that it can (but doesn't have to) skip // this channel ffado_streaming_capture_stream_onoff(driver->dev, chn, 0); } else { if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) { buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], nframes); /* if the returned buffer is invalid, use the dummy buffer */ if (!buf) buf = (jack_default_audio_sample_t*)driver->scratchbuffer; ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(buf)); ffado_streaming_capture_stream_onoff(driver->dev, chn, 1); } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->capture_channels[chn].midi_buffer)); ffado_streaming_capture_stream_onoff(driver->dev, chn, 1); } else { // always have a valid buffer ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer)); // don't process what we don't use ffado_streaming_capture_stream_onoff(driver->dev, chn, 0); } } } /* now transfer the buffers */ ffado_streaming_transfer_capture_buffers(driver->dev); /* process the midi data */ for (chn = 0; chn < driver->capture_nchannels; chn++) { if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { JackFFADOMidiInputPort *midi_input = (JackFFADOMidiInputPort *) driver->capture_channels[chn].midi_input; JackMidiBuffer *buffer = (JackMidiBuffer *) fGraphManager->GetBuffer(fCapturePortList[chn], nframes); midi_input->Process(buffer, driver->capture_channels[chn].midi_buffer, nframes); } } printExit(); return 0; } int JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes) { channel_t chn; jack_default_audio_sample_t* buf; printEnter(); driver->process_count++; for (chn = 0; chn < driver->playback_nchannels; chn++) { if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chn]) == 0) { buf = (jack_default_audio_sample_t*)driver->nullbuffer; // we always have to specify a valid buffer ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf)); // notify the streaming system that it can (but doesn't have to) skip // this channel ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); } else { if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) { buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes); /* use the silent buffer if there is no valid jack buffer */ if (!buf) buf = (jack_default_audio_sample_t*)driver->nullbuffer; ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf)); ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer; memset(midi_buffer, 0, nframes * sizeof(uint32_t)); buf = (jack_default_audio_sample_t *) fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes); ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer)); ffado_streaming_playback_stream_onoff(driver->dev, chn, buf ? 1 : 0); JackFFADOMidiOutputPort *midi_output = (JackFFADOMidiOutputPort *) driver->playback_channels[chn].midi_output; midi_output->Process((JackMidiBuffer *) buf, midi_buffer, nframes); } else { // always have a valid buffer ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); } } } ffado_streaming_transfer_playback_buffers(driver->dev); printExit(); return 0; } jack_nframes_t JackFFADODriver::ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *status, float *delayed_usecs) { jack_time_t wait_enter; jack_time_t wait_ret; ffado_wait_response response; printEnter(); wait_enter = jack_get_microseconds (); if (wait_enter > driver->wait_next) { /* * This processing cycle was delayed past the * next due interrupt! Do not account this as * a wakeup delay: */ driver->wait_next = 0; driver->wait_late++; } // *status = -2; interrupt // *status = -3; timeout // *status = -4; extra FD response = ffado_streaming_wait(driver->dev); wait_ret = jack_get_microseconds (); if (driver->wait_next && wait_ret > driver->wait_next) { *delayed_usecs = wait_ret - driver->wait_next; } driver->wait_last = wait_ret; driver->wait_next = wait_ret + driver->period_usecs; // driver->engine->transport_cycle_start (driver->engine, wait_ret); if(response == ffado_wait_ok) { // all good *status = 0; } else if (response == ffado_wait_xrun) { // xrun happened, but it's handled *status = 0; return 0; } else if (response == ffado_wait_error) { // an error happened (unhandled xrun) // this should be fatal jack_error("JackFFADODriver::ffado_driver_wait - unhandled xrun"); *status = -1; return 0; } else if (response == ffado_wait_shutdown) { // ffado requested shutdown (e.g. device unplugged) // this should be fatal jack_error("JackFFADODriver::ffado_driver_wait - shutdown requested " "(device unplugged?)"); *status = -1; return 0; } else { // unknown response code. should be fatal // this should be fatal jack_error("JackFFADODriver::ffado_driver_wait - unexpected error " "code '%d' returned from 'ffado_streaming_wait'", response); *status = -1; return 0; } fBeginDateUst = wait_ret; printExit(); return driver->period_size; } int JackFFADODriver::ffado_driver_start (ffado_driver_t *driver) { int retval = 0; if ((retval = ffado_streaming_start(driver->dev))) { printError("Could not start streaming threads"); return retval; } return 0; } int JackFFADODriver::ffado_driver_stop (ffado_driver_t *driver) { int retval = 0; if ((retval = ffado_streaming_stop(driver->dev))) { printError("Could not stop streaming threads"); return retval; } return 0; } int JackFFADODriver::ffado_driver_restart (ffado_driver_t *driver) { if (Stop()) return -1; return Start(); } void JackFFADODriver::UpdateLatencies(void) { jack_latency_range_t range; ffado_driver_t* driver = (ffado_driver_t*)fDriver; for (int i = 0; i < fCaptureChannels; i++) { range.min = range.max = driver->period_size + driver->capture_frame_latency; fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); } for (int i = 0; i < fPlaybackChannels; i++) { // Add one buffer more latency if "async" mode is used... range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency; fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); // Monitor port if (fWithMonitorPorts) { range.min = range.max =driver->period_size; fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range); } } } int JackFFADODriver::SetBufferSize (jack_nframes_t nframes) { ffado_driver_t* driver = (ffado_driver_t*)fDriver; signed int chn; // The speed of this function isn't critical; we can afford the // time to check the FFADO API version. if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE || ffado_streaming_set_period_size == NULL) { printError("unsupported on current version of FFADO; please upgrade FFADO"); return -1; } driver->period_size = nframes; driver->period_usecs = (jack_time_t) floor ((((float) nframes) / driver->sample_rate) * 1000000.0f); // Reallocate the null and scratch buffers. driver->nullbuffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(ffado_sample_t)); if(driver->nullbuffer == NULL) { printError("could not allocate memory for null buffer"); return -1; } driver->scratchbuffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(ffado_sample_t)); if(driver->scratchbuffer == NULL) { printError("could not allocate memory for scratch buffer"); return -1; } // MIDI buffers need reallocating for (chn = 0; chn < driver->capture_nchannels; chn++) { if(driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { // setup the midi buffer if (driver->capture_channels[chn].midi_buffer != NULL) free(driver->capture_channels[chn].midi_buffer); driver->capture_channels[chn].midi_buffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(uint32_t)); } } for (chn = 0; chn < driver->playback_nchannels; chn++) { if(driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { if (driver->playback_channels[chn].midi_buffer != NULL) free(driver->playback_channels[chn].midi_buffer); driver->playback_channels[chn].midi_buffer = (ffado_sample_t*) calloc(driver->period_size, sizeof(uint32_t)); } } // Notify FFADO of the period size change if (ffado_streaming_set_period_size(driver->dev, nframes) != 0) { printError("could not alter FFADO device period size"); return -1; } // This is needed to give the shadow variables a chance to // properly update to the changes. sleep(1); /* tell the engine to change its buffer size */ JackAudioDriver::SetBufferSize(nframes); // Generic change, never fails UpdateLatencies(); return 0; } typedef void (*JackDriverFinishFunction) (jack_driver_t *); ffado_driver_t * JackFFADODriver::ffado_driver_new (const char *name, ffado_jack_settings_t *params) { ffado_driver_t *driver; assert(params); if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION) { printError("Incompatible libffado version! (%s)", ffado_get_version()); return NULL; } printMessage("Starting FFADO backend (%s)", ffado_get_version()); driver = (ffado_driver_t*)calloc (1, sizeof (ffado_driver_t)); /* Setup the jack interfaces */ jack_driver_nt_init ((jack_driver_nt_t *) driver); /* driver->nt_attach = (JackDriverNTAttachFunction) ffado_driver_attach; driver->nt_detach = (JackDriverNTDetachFunction) ffado_driver_detach; driver->nt_start = (JackDriverNTStartFunction) ffado_driver_start; driver->nt_stop = (JackDriverNTStopFunction) ffado_driver_stop; driver->nt_run_cycle = (JackDriverNTRunCycleFunction) ffado_driver_run_cycle; driver->null_cycle = (JackDriverNullCycleFunction) ffado_driver_null_cycle; driver->write = (JackDriverReadFunction) ffado_driver_write; driver->read = (JackDriverReadFunction) ffado_driver_read; driver->nt_bufsize = (JackDriverNTBufSizeFunction) ffado_driver_bufsize; */ /* copy command line parameter contents to the driver structure */ memcpy(&driver->settings, params, sizeof(ffado_jack_settings_t)); /* prepare all parameters */ driver->sample_rate = params->sample_rate; driver->period_size = params->period_size; fBeginDateUst = 0; driver->period_usecs = (jack_time_t) floor ((((float) driver->period_size) * 1000000.0f) / driver->sample_rate); // driver->client = client; driver->engine = NULL; //from jack1 ffado_driver.c: put arg -dxxx to ffado device_info_t struct driver->device_info.nb_device_spec_strings=1; driver->device_info.device_spec_strings=(char**)calloc(1, sizeof(char *)); driver->device_info.device_spec_strings[0]=strdup(params->device_info); memset(&driver->device_options, 0, sizeof(driver->device_options)); driver->device_options.sample_rate = params->sample_rate; driver->device_options.period_size = params->period_size; driver->device_options.nb_buffers = params->buffer_size; driver->device_options.verbose = params->verbose_level; driver->capture_frame_latency = params->capture_frame_latency; driver->playback_frame_latency = params->playback_frame_latency; driver->device_options.snoop_mode = params->snoop_mode; debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s", __DATE__, __TIME__); debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name); debugPrint(DEBUG_LEVEL_STARTUP, " period_size: %d", driver->device_options.period_size); debugPrint(DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs); debugPrint(DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->device_options.sample_rate); debugPrint(DEBUG_LEVEL_STARTUP, " verbose level: %d", driver->device_options.verbose); return (ffado_driver_t *) driver; } void JackFFADODriver::ffado_driver_delete (ffado_driver_t *driver) { free (driver); } int JackFFADODriver::Attach() { JackPort* port; jack_port_id_t port_index; char buf[REAL_JACK_PORT_NAME_SIZE]; char portname[REAL_JACK_PORT_NAME_SIZE]; ffado_driver_t* driver = (ffado_driver_t*)fDriver; jack_log("JackFFADODriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); g_verbose = (fEngineControl->fVerbose ? 1 : 0); /* preallocate some buffers such that they don't have to be allocated in RT context (or from the stack) */ /* the null buffer is a buffer that contains one period of silence */ driver->nullbuffer = (ffado_sample_t *)calloc(driver->period_size, sizeof(ffado_sample_t)); if (driver->nullbuffer == NULL) { printError("could not allocate memory for null buffer"); return -1; } /* calloc should do this, but it can't hurt to be sure */ memset(driver->nullbuffer, 0, driver->period_size*sizeof(ffado_sample_t)); /* the scratch buffer is a buffer of one period that can be used as dummy memory */ driver->scratchbuffer = (ffado_sample_t *)calloc(driver->period_size, sizeof(ffado_sample_t)); if (driver->scratchbuffer == NULL) { printError("could not allocate memory for scratch buffer"); return -1; } /* packetizer thread options */ driver->device_options.realtime = (fEngineControl->fRealTime ? 1 : 0); driver->device_options.packetizer_priority = fEngineControl->fServerPriority + FFADO_RT_PRIORITY_PACKETIZER_RELATIVE; if (driver->device_options.packetizer_priority > 98) { driver->device_options.packetizer_priority = 98; } // initialize the thread driver->dev = ffado_streaming_init(driver->device_info, driver->device_options); if (!driver->dev) { printError("FFADO: Error creating virtual device"); return -1; } if (driver->device_options.realtime) { printMessage("Streaming thread running with Realtime scheduling, priority %d", driver->device_options.packetizer_priority); } else { printMessage("Streaming thread running without Realtime scheduling"); } ffado_streaming_set_audio_datatype(driver->dev, ffado_audio_datatype_float); /* ports */ // capture driver->capture_nchannels = ffado_streaming_get_nb_capture_streams(driver->dev); driver->capture_channels = (ffado_capture_channel_t *)calloc(driver->capture_nchannels, sizeof(ffado_capture_channel_t)); if (driver->capture_channels == NULL) { printError("could not allocate memory for capture channel list"); return -1; } fCaptureChannels = 0; for (channel_t chn = 0; chn < driver->capture_nchannels; chn++) { ffado_streaming_get_capture_stream_name(driver->dev, chn, portname, sizeof(portname)); driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type(driver->dev, chn); if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) { snprintf(buf, sizeof(buf), "firewire_pcm:%s_in", portname); printMessage ("Registering audio capture port %s", buf); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } // setup port parameters if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) { printError(" cannot configure initial port buffer for %s", buf); } ffado_streaming_capture_stream_onoff(driver->dev, chn, 0); port = fGraphManager->GetPort(port_index); // capture port aliases (jackd1 style port names) snprintf(buf, sizeof(buf), "%s:capture_%i", fClientControl.fName, (int) chn + 1); port->SetAlias(buf); fCapturePortList[chn] = port_index; jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index); fCaptureChannels++; } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { snprintf(buf, sizeof(buf), "firewire_pcm:%s_in", portname); printMessage ("Registering midi capture port %s", buf); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } // setup port parameters if (ffado_streaming_set_capture_stream_buffer(driver->dev, chn, NULL)) { printError(" cannot configure initial port buffer for %s", buf); } if (ffado_streaming_capture_stream_onoff(driver->dev, chn, 0)) { printError(" cannot enable port %s", buf); } driver->capture_channels[chn].midi_input = new JackFFADOMidiInputPort(); // setup the midi buffer driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); fCapturePortList[chn] = port_index; jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index); fCaptureChannels++; } else { printMessage ("Don't register capture port %s", portname); } } // playback driver->playback_nchannels = ffado_streaming_get_nb_playback_streams(driver->dev); driver->playback_channels = (ffado_playback_channel_t *)calloc(driver->playback_nchannels, sizeof(ffado_playback_channel_t)); if (driver->playback_channels == NULL) { printError("could not allocate memory for playback channel list"); return -1; } fPlaybackChannels = 0; for (channel_t chn = 0; chn < driver->playback_nchannels; chn++) { ffado_streaming_get_playback_stream_name(driver->dev, chn, portname, sizeof(portname)); driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type(driver->dev, chn); if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) { snprintf(buf, sizeof(buf), "firewire_pcm:%s_out", portname); printMessage ("Registering audio playback port %s", buf); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } // setup port parameters if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) { printError(" cannot configure initial port buffer for %s", buf); } if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) { printError(" cannot enable port %s", buf); } port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... // playback port aliases (jackd1 style port names) snprintf(buf, sizeof(buf), "%s:playback_%i", fClientControl.fName, (int) chn + 1); port->SetAlias(buf); fPlaybackPortList[chn] = port_index; jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index); fPlaybackChannels++; } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { snprintf(buf, sizeof(buf), "firewire_pcm:%s_out", portname); printMessage ("Registering midi playback port %s", buf); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } // setup port parameters if (ffado_streaming_set_playback_stream_buffer(driver->dev, chn, NULL)) { printError(" cannot configure initial port buffer for %s", buf); } if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) { printError(" cannot enable port %s", buf); } // setup the midi buffer // This constructor optionally accepts arguments for the // non-realtime buffer size and the realtime buffer size. Ideally, // these would become command-line options for the FFADO driver. driver->playback_channels[chn].midi_output = new JackFFADOMidiOutputPort(); driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); fPlaybackPortList[chn] = port_index; jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index); fPlaybackChannels++; } else { printMessage ("Don't register playback port %s", portname); } } UpdateLatencies(); assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); if (ffado_streaming_prepare(driver->dev)) { printError("Could not prepare streaming device!"); return -1; } // this makes no sense... assert(fCaptureChannels + fPlaybackChannels > 0); return 0; } int JackFFADODriver::Detach() { channel_t chn; ffado_driver_t* driver = (ffado_driver_t*)fDriver; jack_log("JackFFADODriver::Detach"); // finish the libfreebob streaming ffado_streaming_finish(driver->dev); driver->dev = NULL; // free all internal buffers for (chn = 0; chn < driver->capture_nchannels; chn++) { if (driver->capture_channels[chn].midi_buffer) free(driver->capture_channels[chn].midi_buffer); if (driver->capture_channels[chn].midi_input) delete ((JackFFADOMidiInputPort *) (driver->capture_channels[chn].midi_input)); } free(driver->capture_channels); for (chn = 0; chn < driver->playback_nchannels; chn++) { if (driver->playback_channels[chn].midi_buffer) free(driver->playback_channels[chn].midi_buffer); if (driver->playback_channels[chn].midi_output) delete ((JackFFADOMidiOutputPort *) (driver->playback_channels[chn].midi_output)); } free(driver->playback_channels); free(driver->nullbuffer); free(driver->scratchbuffer); return JackAudioDriver::Detach(); // Generic JackAudioDriver Detach } int JackFFADODriver::Open(ffado_jack_settings_t *params) { // Generic JackAudioDriver Open if (JackAudioDriver::Open( params->period_size, params->sample_rate, params->playback_ports, params->playback_ports, 0, 0, 0, "", "", params->capture_frame_latency, params->playback_frame_latency) != 0) { return -1; } fDriver = (jack_driver_t *)ffado_driver_new ("ffado_pcm", params); if (fDriver) { // FFADO driver may have changed the in/out values //fCaptureChannels = ((ffado_driver_t *)fDriver)->capture_nchannels_audio; //fPlaybackChannels = ((ffado_driver_t *)fDriver)->playback_nchannels_audio; return 0; } else { JackAudioDriver::Close(); return -1; } } int JackFFADODriver::Close() { // Generic audio driver close int res = JackAudioDriver::Close(); ffado_driver_delete((ffado_driver_t*)fDriver); return res; } int JackFFADODriver::Start() { int res = JackAudioDriver::Start(); if (res >= 0) { res = ffado_driver_start((ffado_driver_t *)fDriver); if (res < 0) { JackAudioDriver::Stop(); } } return res; } int JackFFADODriver::Stop() { int res = ffado_driver_stop((ffado_driver_t *)fDriver); if (JackAudioDriver::Stop() < 0) { res = -1; } return res; } int JackFFADODriver::Read() { printEnter(); /* Taken from ffado_driver_run_cycle */ ffado_driver_t* driver = (ffado_driver_t*)fDriver; int wait_status = 0; fDelayedUsecs = 0.f; retry: jack_nframes_t nframes = ffado_driver_wait(driver, -1, &wait_status, &fDelayedUsecs); if ((wait_status < 0)) { printError( "wait status < 0! (= %d)", wait_status); return -1; } if (nframes == 0) { /* we detected an xrun and restarted: notify * clients about the delay. */ jack_log("FFADO XRun"); NotifyXRun(fBeginDateUst, fDelayedUsecs); goto retry; /* recoverable error*/ } if (nframes != fEngineControl->fBufferSize) jack_log("JackFFADODriver::Read warning nframes = %ld", nframes); // Has to be done before read JackDriver::CycleIncTime(); printExit(); return ffado_driver_read((ffado_driver_t *)fDriver, fEngineControl->fBufferSize); } int JackFFADODriver::Write() { printEnter(); int res = ffado_driver_write((ffado_driver_t *)fDriver, fEngineControl->fBufferSize); printExit(); return res; } void JackFFADODriver::jack_driver_init (jack_driver_t *driver) { memset (driver, 0, sizeof (*driver)); driver->attach = 0; driver->detach = 0; driver->write = 0; driver->read = 0; driver->null_cycle = 0; driver->bufsize = 0; driver->start = 0; driver->stop = 0; } void JackFFADODriver::jack_driver_nt_init (jack_driver_nt_t * driver) { memset (driver, 0, sizeof (*driver)); jack_driver_init ((jack_driver_t *) driver); driver->attach = 0; driver->detach = 0; driver->bufsize = 0; driver->stop = 0; driver->start = 0; driver->nt_bufsize = 0; driver->nt_start = 0; driver->nt_stop = 0; driver->nt_attach = 0; driver->nt_detach = 0; driver->nt_run_cycle = 0; } } // end of namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT const jack_driver_desc_t * driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("firewire", JackDriverMaster, "Linux FFADO API based audio backend", &filler); strcpy(value.str, "hw:0"); jack_driver_descriptor_add_parameter( desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "The FireWire device to use.", "The FireWire device to use. Please consult the FFADO documentation for more info."); value.ui = 1024; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = 3; jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods of playback latency", NULL); value.ui = 48000U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamBool, &value, NULL, "Provide capture ports.", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamBool, &value, NULL, "Provide playback ports.", NULL); value.i = 1; jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports.", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency (frames)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency (frames)", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Number of input channels to provide (note: currently ignored)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Number of output channels to provide (note: currently ignored)", NULL); value.ui = 3; jack_driver_descriptor_add_parameter(desc, &filler, "verbose", 'v', JackDriverParamUInt, &value, NULL, "libffado verbose level", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "snoop", 'X', JackDriverParamBool, &value, NULL, "Snoop firewire traffic", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { const JSList * node; const jack_driver_param_t * param; ffado_jack_settings_t cmlparams; char *device_name=(char*)"hw:0"; cmlparams.period_size_set = 0; cmlparams.sample_rate_set = 0; cmlparams.buffer_size_set = 0; /* default values */ cmlparams.period_size = 1024; cmlparams.sample_rate = 48000; cmlparams.buffer_size = 3; cmlparams.playback_ports = 0; cmlparams.capture_ports = 0; cmlparams.playback_frame_latency = 0; cmlparams.capture_frame_latency = 0; cmlparams.verbose_level = 0; cmlparams.slave_mode = 0; cmlparams.snoop_mode = 0; cmlparams.device_info = NULL; for (node = params; node; node = jack_slist_next (node)) { param = (jack_driver_param_t *) node->data; switch (param->character) { case 'd': device_name = const_cast(param->value.str); break; case 'p': cmlparams.period_size = param->value.ui; cmlparams.period_size_set = 1; break; case 'n': cmlparams.buffer_size = param->value.ui; cmlparams.buffer_size_set = 1; break; case 'r': cmlparams.sample_rate = param->value.ui; cmlparams.sample_rate_set = 1; break; case 'i': cmlparams.capture_ports = param->value.ui; break; case 'o': cmlparams.playback_ports = param->value.ui; break; case 'I': cmlparams.capture_frame_latency = param->value.ui; break; case 'O': cmlparams.playback_frame_latency = param->value.ui; break; case 'x': cmlparams.slave_mode = param->value.ui; break; case 'X': cmlparams.snoop_mode = param->value.i; break; case 'v': cmlparams.verbose_level = param->value.ui; } } /* duplex is the default */ if (!cmlparams.playback_ports && !cmlparams.capture_ports) { cmlparams.playback_ports = 1; cmlparams.capture_ports = 1; } // temporary cmlparams.device_info = device_name; Jack::JackFFADODriver* ffado_driver = new Jack::JackFFADODriver("system", "firewire_pcm", engine, table); Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(ffado_driver); // Special open for FFADO driver... if (ffado_driver->Open(&cmlparams) == 0) { return threaded_driver; } else { delete threaded_driver; // Delete the decorated driver return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/linux/firewire/JackFFADOMidiReceiveQueue.cpp0000644000000000000000000000310713214314510021543 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackFFADOMidiReceiveQueue.h" #include "JackMidiUtil.h" using Jack::JackFFADOMidiReceiveQueue; JackFFADOMidiReceiveQueue::JackFFADOMidiReceiveQueue() { // Empty } jack_midi_event_t * JackFFADOMidiReceiveQueue::DequeueEvent() { for (; index < length; index += 8) { uint32_t data = input_buffer[index]; if (data & 0xff000000) { byte = (jack_midi_data_t) (data & 0xff); event.buffer = &byte; event.size = 1; event.time = last_frame + index; index += 8; return &event; } } return 0; } void JackFFADOMidiReceiveQueue::ResetInputBuffer(uint32_t *input_buffer, jack_nframes_t length) { this->input_buffer = input_buffer; index = 0; last_frame = GetLastFrame(); this->length = length; } 1.9.12~dfsg/linux/firewire/JackFFADOMidiInputPort.cpp0000644000000000000000000000662313214314510021126 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "JackFFADOMidiInputPort.h" #include "JackMidiUtil.h" #include "JackError.h" using Jack::JackFFADOMidiInputPort; JackFFADOMidiInputPort::JackFFADOMidiInputPort(size_t max_bytes) { event = 0; receive_queue = new JackFFADOMidiReceiveQueue(); std::auto_ptr receive_queue_ptr(receive_queue); write_queue = new JackMidiBufferWriteQueue(); std::auto_ptr write_queue_ptr(write_queue); raw_queue = new JackMidiRawInputWriteQueue(write_queue, max_bytes, max_bytes); write_queue_ptr.release(); receive_queue_ptr.release(); } JackFFADOMidiInputPort::~JackFFADOMidiInputPort() { delete raw_queue; delete receive_queue; delete write_queue; } void JackFFADOMidiInputPort::Process(JackMidiBuffer *port_buffer, uint32_t *input_buffer, jack_nframes_t frames) { receive_queue->ResetInputBuffer(input_buffer, frames); write_queue->ResetMidiBuffer(port_buffer, frames); jack_nframes_t boundary_frame = GetLastFrame() + frames; if (! event) { event = receive_queue->DequeueEvent(); } for (; event; event = receive_queue->DequeueEvent()) { switch (raw_queue->EnqueueEvent(event)) { case JackMidiWriteQueue::BUFFER_FULL: // Processing events early might free up some space in the raw // input queue. raw_queue->Process(boundary_frame); switch (raw_queue->EnqueueEvent(event)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: // This shouldn't really happen. It indicates a bug if it // does. jack_error("JackFFADOMidiInputPort::Process - **BUG** " "JackMidiRawInputWriteQueue::EnqueueEvent returned " "`BUFFER_FULL`, and then returned " "`BUFFER_TOO_SMALL` after a `Process()` call."); // Fallthrough on purpose case JackMidiWriteQueue::OK: continue; default: return; } case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackFFADOMidiInputPort::Process - The write queue " "couldn't enqueue a %d-byte event. Dropping event.", event->size); // Fallthrough on purpose case JackMidiWriteQueue::OK: continue; default: // This is here to stop compliers from warning us about not // handling enumeration values. ; } break; } raw_queue->Process(boundary_frame); } 1.9.12~dfsg/linux/firewire/JackFFADOMidiReceiveQueue.h0000644000000000000000000000251513214314510021212 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackFFADOMidiReceiveQueue__ #define __JackFFADOMidiReceiveQueue__ #include "JackMidiReceiveQueue.h" namespace Jack { class JackFFADOMidiReceiveQueue: public JackMidiReceiveQueue { private: jack_midi_data_t byte; jack_midi_event_t event; jack_nframes_t index; uint32_t *input_buffer; jack_nframes_t last_frame; jack_nframes_t length; public: JackFFADOMidiReceiveQueue(); jack_midi_event_t * DequeueEvent(); void ResetInputBuffer(uint32_t *input_buffer, jack_nframes_t length); }; } #endif 1.9.12~dfsg/linux/firewire/JackFFADOMidiSendQueue.h0000644000000000000000000000257713214314510020531 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackFFADOMidiSendQueue__ #define __JackFFADOMidiSendQueue__ #include "JackMidiSendQueue.h" namespace Jack { class JackFFADOMidiSendQueue: public JackMidiSendQueue { private: jack_nframes_t index; jack_nframes_t last_frame; jack_nframes_t length; uint32_t *output_buffer; public: JackFFADOMidiSendQueue(); EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); jack_nframes_t GetNextScheduleFrame(); void ResetOutputBuffer(uint32_t *output_buffer, jack_nframes_t length); }; } #endif 1.9.12~dfsg/linux/JackLinuxFutex.cpp0000644000000000000000000001613013214314510016110 0ustar rootroot/* Copyright (C) 2004-2008 Grame Copyright (C) 2016 Filipe Coelho This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackLinuxFutex.h" #include "JackTools.h" #include "JackConstants.h" #include "JackError.h" #include "promiscuous.h" #include #include #include #include #include namespace Jack { JackLinuxFutex::JackLinuxFutex() : JackSynchro(), fSharedMem(-1), fFutex(NULL), fPrivate(false) { const char* promiscuous = getenv("JACK_PROMISCUOUS_SERVER"); fPromiscuous = (promiscuous != NULL); fPromiscuousGid = jack_group2gid(promiscuous); } void JackLinuxFutex::BuildName(const char* client_name, const char* server_name, char* res, int size) { char ext_client_name[SYNC_MAX_NAME_SIZE + 1]; JackTools::RewriteName(client_name, ext_client_name); if (fPromiscuous) { snprintf(res, size, "jack_sem.%s_%s", server_name, ext_client_name); } else { snprintf(res, size, "jack_sem.%d_%s_%s", JackTools::GetUID(), server_name, ext_client_name); } } bool JackLinuxFutex::Signal() { if (!fFutex) { jack_error("JackLinuxFutex::Signal name = %s already deallocated!!", fName); return false; } if (fFlush) { return true; } if (! __sync_bool_compare_and_swap(&fFutex->futex, 0, 1)) { // already unlocked, do not wake futex if (! fFutex->internal) return true; } ::syscall(__NR_futex, fFutex, fFutex->internal ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1, NULL, NULL, 0); return true; } bool JackLinuxFutex::SignalAll() { return Signal(); } bool JackLinuxFutex::Wait() { if (!fFutex) { jack_error("JackLinuxFutex::Wait name = %s already deallocated!!", fName); return false; } if (fFutex->needsChange) { fFutex->needsChange = false; fFutex->internal = !fFutex->internal; } for (;;) { if (__sync_bool_compare_and_swap(&fFutex->futex, 1, 0)) return true; if (::syscall(__NR_futex, fFutex, fFutex->internal ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, 0, NULL, NULL, 0) != 0 && errno != EWOULDBLOCK) return false; } } bool JackLinuxFutex::TimedWait(long usec) { if (!fFutex) { jack_error("JackLinuxFutex::TimedWait name = %s already deallocated!!", fName); return false; } if (fFutex->needsChange) { fFutex->needsChange = false; fFutex->internal = !fFutex->internal; } const uint secs = usec / 1000000; const int nsecs = (usec % 1000000) * 1000; const timespec timeout = { static_cast(secs), nsecs }; for (;;) { if (__sync_bool_compare_and_swap(&fFutex->futex, 1, 0)) return true; if (::syscall(__NR_futex, fFutex, fFutex->internal ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, 0, &timeout, NULL, 0) != 0 && errno != EWOULDBLOCK) return false; } } // Server side : publish the futex in the global namespace bool JackLinuxFutex::Allocate(const char* name, const char* server_name, int value, bool internal) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackLinuxFutex::Allocate name = %s val = %ld", fName, value); if ((fSharedMem = shm_open(fName, O_CREAT | O_RDWR, 0777)) < 0) { jack_error("Allocate: can't check in named futex name = %s err = %s", fName, strerror(errno)); return false; } ftruncate(fSharedMem, sizeof(FutexData)); if (fPromiscuous && (jack_promiscuous_perms(fSharedMem, fName, fPromiscuousGid) < 0)) { close(fSharedMem); fSharedMem = -1; shm_unlink(fName); return false; } if ((fFutex = (FutexData*)mmap(NULL, sizeof(FutexData), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, fSharedMem, 0)) == NULL) { jack_error("Allocate: can't check in named futex name = %s err = %s", fName, strerror(errno)); close(fSharedMem); fSharedMem = -1; shm_unlink(fName); return false; } fPrivate = internal; fFutex->futex = value; fFutex->internal = internal; fFutex->wasInternal = internal; fFutex->needsChange = false; fFutex->externalCount = 0; return true; } // Client side : get the published futex from server bool JackLinuxFutex::Connect(const char* name, const char* server_name) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackLinuxFutex::Connect name = %s", fName); // Temporary... if (fFutex) { jack_log("Already connected name = %s", name); return true; } if ((fSharedMem = shm_open(fName, O_RDWR, 0)) < 0) { jack_error("Connect: can't connect named futex name = %s err = %s", fName, strerror(errno)); return false; } if ((fFutex = (FutexData*)mmap(NULL, sizeof(FutexData), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, fSharedMem, 0)) == NULL) { jack_error("Connect: can't connect named futex name = %s err = %s", fName, strerror(errno)); close(fSharedMem); fSharedMem = -1; return false; } if (! fPrivate && fFutex->wasInternal) { const char* externalSync = getenv("JACK_INTERNAL_CLIENT_SYNC"); if (externalSync != NULL && strstr(fName, externalSync) != NULL && ++fFutex->externalCount == 1) { jack_error("Note: client %s running as external client temporarily", fName); fFutex->needsChange = true; } } return true; } bool JackLinuxFutex::ConnectInput(const char* name, const char* server_name) { return Connect(name, server_name); } bool JackLinuxFutex::ConnectOutput(const char* name, const char* server_name) { return Connect(name, server_name); } bool JackLinuxFutex::Disconnect() { if (!fFutex) { return true; } if (! fPrivate && fFutex->wasInternal) { const char* externalSync = getenv("JACK_INTERNAL_CLIENT_SYNC"); if (externalSync != NULL && strstr(fName, externalSync) != NULL && --fFutex->externalCount == 0) { jack_error("Note: client %s now running as internal client again", fName); fFutex->needsChange = true; } } munmap(fFutex, sizeof(FutexData)); fFutex = NULL; close(fSharedMem); fSharedMem = -1; return true; } // Server side : destroy the futex void JackLinuxFutex::Destroy() { if (!fFutex) { return; } munmap(fFutex, sizeof(FutexData)); fFutex = NULL; close(fSharedMem); fSharedMem = -1; shm_unlink(fName); } } // end of namespace 1.9.12~dfsg/linux/iio/0000755000000000000000000000000013214314510013257 5ustar rootroot1.9.12~dfsg/linux/iio/JackIIODriver.cpp0000644000000000000000000002333713214314510016360 0ustar rootroot/* Copyright (C) 2013 Matt Flax This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackIIODriver.h" #include "driver_interface.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include #define IIO_DEFAULT_CHIP "AD7476A" ///< The default IIO recording chip to look for. #define IIO_DEFAULT_READ_FS 1.e6 ///< The default IIO sample rate for the default chip. #define IIO_DEFAULT_PERIOD_SIZE 2048 ///< The default period size is in the ms range #define IIO_DEFAULT_PERIOD_COUNT 2 ///< The default number of periods #define IIO_DEFAULT_CAPUTURE_PORT_COUNT MAXINT ///< The default number of capture ports is exceedingly big, trimmed down to a realistic size in driver_initialize //#define IIO_SAFETY_FACTOR 2./3. ///< The default safety factor, allow consumption of this fraction of the available DMA buffer before we don't allow the driver to continue. #define IIO_SAFETY_FACTOR 1. ///< The default safety factor, allow consumption of this fraction of the available DMA buffer before we don't allow the driver to continue. namespace Jack { int JackIIODriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { //cout<<"JackIIODriver::Open\n"; int ret=JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); if (ret!=NO_ERROR) // check whether the JackAudioDriver opened OK return ret; ret=iio.enable(true); // start the DMA return ret; } int JackIIODriver::Close() { //cout<<"JackIIODriver::Close\n"; iio.enable(false); // stop the DMA return JackAudioDriver::Close(); } int JackIIODriver::Read() { //cout<<"JackIIODriver::Read\n"; if (iio.getDeviceCnt()<1) { jack_error("JackIIODriver:: No IIO devices are present "); return -1; } uint devChCnt=iio[0].getChCnt(); // the number of channels per device jack_nframes_t nframes=data.rows()/devChCnt; // This is left here for future debugging. // if (nframes != fEngineControl->fBufferSize) // jack_error("JackIIODriver::Read warning : Jack period size = %ld IIO period size = %ld", fEngineControl->fBufferSize, nframes); // cout<<"processing buffer size : "<fBufferSize<maxAvailChCnt) // jack_error("JackIIODriver::Read warning : Jack capture ch. cnt = %ld IIO capture ch. cnt = %ld", fCaptureChannels, maxAvailChCnt); for (int i = 0; i < fCaptureChannels; i++) { int col=i/devChCnt; // find the column and offset to read from int rowOffset=i%devChCnt; if (fGraphManager->GetConnectionsNum(fCapturePortList[i]) > 0) { jack_default_audio_sample_t *dest=GetInputBuffer(i); for (jack_nframes_t j=0; jdata; switch (param->character) { case 'C': // we are specifying a new chip name chipName = param->value.str; break; case 'i': // we are specifying the number of capture channels inChCnt = param->value.ui; break; case 'p': periodSize = param->value.ui; break; case 'n': periodCount = param->value.ui; break; } } // create the driver which contains the IIO class Jack::JackIIODriver* iio_driver = new Jack::JackIIODriver("system", "iio_pcm", engine, table); if (!iio_driver) { jack_error("\nHave you run out of memory ? I tried to create the IIO driver in memory but failed!\n"); return NULL; } // interrogate the available iio devices searching for the chip name if (iio_driver->iio.findDevicesByChipName(chipName)!=NO_ERROR) { // find all devices with a particular chip which are present. jack_error("\nThe iio driver found no devices by the name %s\n", chipName.c_str()); goto initError; } if (iio_driver->iio.getDeviceCnt()<1) { // If there are no devices found by that chip name, then indicate. jack_error("\nThe iio driver found no devices by the name %s\n", chipName.c_str()); goto initError; } iio_driver->iio.printInfo(); // print out detail about the devices which were found ... // if the available number of ports is less then the requested number, then restrict to the number of physical ports. if (iio_driver->iio.getChCnt()iio.getChCnt(); // resize the data buffer column count to match the device count colCnt=(int)ceil((float)inChCnt/(float)iio_driver->iio[0].getChCnt()); // check whether we require less then the available number of channels ret=iio_driver->iio.getReadArray(periodSize, iio_driver->data); // resize the array to be able to read enough memory if (ret!=NO_ERROR) { jack_error("iio::getReadArray couldn't create the data buffer, indicating the problem."); goto initError; } if (iio_driver->data.cols()>colCnt) // resize the data columns to match the specified number of columns (channels / channels per device) iio_driver->data.resize(iio_driver->data.rows(), colCnt); ret=iio_driver->iio.open(periodCount, periodSize); // try to open all IIO devices if (ret!=NO_ERROR) goto initError; threaded_driver = new Jack::JackThreadedDriver(iio_driver); if (threaded_driver) { bool capture=true, playback=false, monitor=false; int outChCnt=0; jack_nframes_t inputLatency = periodSize*periodCount, outputLatency=0; // Special open for OSS driver... if (iio_driver->Open(periodSize, (jack_nframes_t)fs, capture, playback, inChCnt, outChCnt, monitor, "iio:device", "iio:device", inputLatency, outputLatency)!=0) { delete threaded_driver; delete iio_driver; return NULL; } } else jack_error("\nHave you run out of memory ? I tried to create Jack's standard threaded driver in memory but failed! The good news is that you had enough memory to create the IIO driver.\n"); return threaded_driver; initError: // error during intialisation, delete and return NULL delete iio_driver; return NULL; } #ifdef __cplusplus } #endif 1.9.12~dfsg/linux/iio/JackIIODriver.h0000644000000000000000000000447313214314510016025 0ustar rootroot/* Copyright (C) 2013 Matt Flax This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef JACKIIODRIVER_H #define JACKIIODRIVER_H #include "JackAudioDriver.h" #include "JackThreadedDriver.h" #include namespace Jack { /** The Linux Industrial IO (IIO) subsystem driver for Jack. Currently this driver only supports capture. */ class JackIIODriver : public JackAudioDriver { public: IIOMMap iio; ///< The actual IIO devices Eigen::Array data; ///< When we grab a mmapped buffer, store it here. /** Constructor */ JackIIODriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table) { } /** Destructor */ virtual ~JackIIODriver() { } virtual int Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); virtual int Close(); virtual int Read(); ///< Read from the IIO sysetm and load the jack buffers virtual int Write(); ///< Not implemented. virtual int SetBufferSize(jack_nframes_t buffer_size) { //cout<<"JackIIODriver::SetBufferSize("< #include "types.h" #include "jslist.h" #include "driver_interface.h" typedef float gain_t; typedef long channel_t; typedef enum { Lock = 0x1, NoLock = 0x2, Sync = 0x4, NoSync = 0x8 } ClockSyncStatus; typedef void (*ClockSyncListenerFunction)(channel_t, ClockSyncStatus, void*); typedef struct { unsigned long id; ClockSyncListenerFunction function; void *arg; } ClockSyncListener; struct _jack_engine; struct _jack_driver; typedef int (*JackDriverAttachFunction)(struct _jack_driver *, struct _jack_engine *); typedef int (*JackDriverDetachFunction)(struct _jack_driver *, struct _jack_engine *); typedef int (*JackDriverReadFunction)(struct _jack_driver *, jack_nframes_t nframes); typedef int (*JackDriverWriteFunction)(struct _jack_driver *, jack_nframes_t nframes); typedef int (*JackDriverNullCycleFunction)(struct _jack_driver *, jack_nframes_t nframes); typedef int (*JackDriverStopFunction)(struct _jack_driver *); typedef int (*JackDriverStartFunction)(struct _jack_driver *); typedef int (*JackDriverBufSizeFunction)(struct _jack_driver *, jack_nframes_t nframes); /* Call sequence summary: 1) engine loads driver via runtime dynamic linking - calls jack_driver_load - we call dlsym for "driver_initialize" and execute it 2) engine attaches to driver 3) engine starts driver 4) driver runs its own thread, calling while () { driver->wait (); driver->engine->run_cycle () } 5) engine stops driver 6) engine detaches from driver 7) engine calls driver `finish' routine Note that stop/start may be called multiple times in the event of an error return from the `wait' function. */ typedef struct _jack_driver { /* The _jack_driver structure fields are included at the beginning of each driver-specific structure using the JACK_DRIVER_DECL macro, which is defined below. The comments that follow describe each common field. The driver should set this to be the interval it expects to elapse between returning from the `wait' function. if set to zero, it implies that the driver does not expect regular periodic wakeups. jack_time_t period_usecs; The driver should set this within its "wait" function to indicate the UST of the most recent determination that the engine cycle should run. it should not be set if the "extra_fd" argument of the wait function is set to a non-zero value. jack_time_t last_wait_ust; These are not used by the driver. They should not be written to or modified in any way void *handle; struct _jack_internal_client *internal_client; This should perform any cleanup associated with the driver. it will be called when jack server process decides to get rid of the driver. in some systems, it may not be called at all, so the driver should never rely on a call to this. it can set it to NULL if it has nothing do do. void (*finish)(struct _jack_driver *); The JACK engine will call this when it wishes to attach itself to the driver. the engine will pass a pointer to itself, which the driver may use in anyway it wishes to. the driver may assume that this is the same engine object that will make `wait' calls until a `detach' call is made. JackDriverAttachFunction attach; The JACK engine will call this when it is finished using a driver. JackDriverDetachFunction detach; The JACK engine will call this when it wants to wait until the driver decides that its time to process some data. the driver returns a count of the number of audioframes that can be processed. it should set the variable pointed to by `status' as follows: zero: the wait completed normally, processing may begin negative: the wait failed, and recovery is not possible positive: the wait failed, and the driver stopped itself. a call to `start' will return the driver to a correct and known state. the driver should also fill out the `delayed_usecs' variable to indicate any delay in its expected periodic execution. for example, if it discovers that its return from poll(2) is later than it expects it to be, it would place an estimate of the delay in this variable. the engine will use this to decide if it plans to continue execution. JackDriverWaitFunction wait; The JACK engine will call this to ask the driver to move data from its inputs to its output port buffers. it should return 0 to indicate successful completion, negative otherwise. This function will always be called after the wait function (above). JackDriverReadFunction read; The JACK engine will call this to ask the driver to move data from its input port buffers to its outputs. it should return 0 to indicate successful completion, negative otherwise. this function will always be called after the read function (above). JackDriverWriteFunction write; The JACK engine will call this after the wait function (above) has been called, but for some reason the engine is unable to execute a full "cycle". the driver should do whatever is necessary to keep itself running correctly, but cannot reference ports or other JACK data structures in any way. JackDriverNullCycleFunction null_cycle; The engine will call this when it plans to stop calling the `wait' function for some period of time. the driver should take appropriate steps to handle this (possibly no steps at all). NOTE: the driver must silence its capture buffers (if any) from within this function or the function that actually implements the change in state. JackDriverStopFunction stop; The engine will call this to let the driver know that it plans to start calling the `wait' function on a regular basis. the driver should take any appropriate steps to handle this (possibly no steps at all). NOTE: The driver may wish to silence its playback buffers (if any) from within this function or the function that actually implements the change in state. JackDriverStartFunction start; The engine will call this to let the driver know that some client has requested a new buffer size. The stop function will be called prior to this, and the start function after this one has returned. JackDriverBufSizeFunction bufsize; */ /* define the fields here... */ #define JACK_DRIVER_DECL \ jack_time_t period_usecs; \ jack_time_t last_wait_ust; \ void *handle; \ struct _jack_client_internal * internal_client; \ void (*finish)(struct _jack_driver *);\ JackDriverAttachFunction attach; \ JackDriverDetachFunction detach; \ JackDriverReadFunction read; \ JackDriverWriteFunction write; \ JackDriverNullCycleFunction null_cycle; \ JackDriverStopFunction stop; \ JackDriverStartFunction start; \ JackDriverBufSizeFunction bufsize; JACK_DRIVER_DECL /* expand the macro */ } jack_driver_t; void jack_driver_init (jack_driver_t *); void jack_driver_release (jack_driver_t *); jack_driver_t *jack_driver_load (int argc, char **argv); void jack_driver_unload (jack_driver_t *); /**************************** *** Non-Threaded Drivers *** ****************************/ /* Call sequence summary: 1) engine loads driver via runtime dynamic linking - calls jack_driver_load - we call dlsym for "driver_initialize" and execute it - driver_initialize calls jack_driver_nt_init 2) nt layer attaches to driver 3) nt layer starts driver 4) nt layer runs a thread, calling while () { driver->nt_run_ctcle(); } 5) nt layer stops driver 6) nt layer detaches driver 7) engine calls driver `finish' routine which calls jack_driver_nt_finish Note that stop/start may be called multiple times in the event of an error return from the `wait' function. */ struct _jack_driver_nt; typedef int (*JackDriverNTAttachFunction)(struct _jack_driver_nt *); typedef int (*JackDriverNTDetachFunction)(struct _jack_driver_nt *); typedef int (*JackDriverNTStopFunction)(struct _jack_driver_nt *); typedef int (*JackDriverNTStartFunction)(struct _jack_driver_nt *); typedef int (*JackDriverNTBufSizeFunction)(struct _jack_driver_nt *, jack_nframes_t nframes); typedef int (*JackDriverNTRunCycleFunction)(struct _jack_driver_nt *); typedef struct _jack_driver_nt { #define JACK_DRIVER_NT_DECL \ JACK_DRIVER_DECL \ struct _jack_engine * engine; \ volatile int nt_run; \ pthread_t nt_thread; \ pthread_mutex_t nt_run_lock; \ JackDriverNTAttachFunction nt_attach; \ JackDriverNTDetachFunction nt_detach; \ JackDriverNTStopFunction nt_stop; \ JackDriverNTStartFunction nt_start; \ JackDriverNTBufSizeFunction nt_bufsize; \ JackDriverNTRunCycleFunction nt_run_cycle; #define nt_read read #define nt_write write #define nt_null_cycle null_cycle JACK_DRIVER_NT_DECL } jack_driver_nt_t; void jack_driver_nt_init (jack_driver_nt_t * driver); void jack_driver_nt_finish (jack_driver_nt_t * driver); #endif /* __jack_driver_h__ */ 1.9.12~dfsg/linux/freebob/0000755000000000000000000000000013214314510014103 5ustar rootroot1.9.12~dfsg/linux/freebob/freebob_driver.h0000644000000000000000000001461613214314510017243 0ustar rootroot/* freebob_driver.h * * FreeBob Backend for Jack * FreeBob = Firewire (pro-)audio for linux * * adapted for jackmp * * http://freebob.sf.net * http://jackit.sf.net * * Copyright (C) 2005,2006,2007 Pieter Palmers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Main Jack driver entry routines * */ #ifndef __JACK_FREEBOB_DRIVER_H__ #define __JACK_FREEBOB_DRIVER_H__ // #define FREEBOB_DRIVER_WITH_MIDI // #define DEBUG_ENABLED #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef FREEBOB_DRIVER_WITH_MIDI #include #include #endif // debug print control flags #define DEBUG_LEVEL_BUFFERS (1<<0) #define DEBUG_LEVEL_HANDLERS (1<<1) #define DEBUG_LEVEL_XRUN_RECOVERY (1<<2) #define DEBUG_LEVEL_WAIT (1<<3) #define DEBUG_LEVEL_RUN_CYCLE (1<<8) #define DEBUG_LEVEL_PACKETCOUNTER (1<<16) #define DEBUG_LEVEL_STARTUP (1<<17) #define DEBUG_LEVEL_THREADS (1<<18) #ifdef DEBUG_ENABLED // default debug level #define DEBUG_LEVEL ( DEBUG_LEVEL_RUN_CYCLE | \ (DEBUG_LEVEL_XRUN_RECOVERY)| DEBUG_LEVEL_STARTUP | DEBUG_LEVEL_WAIT | DEBUG_LEVEL_PACKETCOUNTER) #warning Building debug build! #define printMessage(format, args...) jack_error( "FreeBoB MSG: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) #define printError(format, args...) jack_error( "FreeBoB ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) /* #define printEnter() jack_error( "FBDRV ENTERS: %s (%s)", __FUNCTION__, __FILE__) #define printExit() jack_error( "FBDRV EXITS: %s (%s)", __FUNCTION__, __FILE__)*/ #define printEnter() #define printExit() #define debugError(format, args...) jack_error( "FREEBOB ERR: %s:%d (%s): " format, __FILE__, __LINE__, __FUNCTION__, ##args ) #define debugPrint(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error("DEBUG %s:%d (%s) :" format, __FILE__, __LINE__, __FUNCTION__, ##args ); #define debugPrintShort(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error( format,##args ); #define debugPrintWithTimeStamp(Level, format, args...) if(DEBUG_LEVEL & (Level)) jack_error( "%16lu: "format, debugGetCurrentUTime(),##args ); #define SEGFAULT int *test=NULL; *test=1; #else #define DEBUG_LEVEL #define printMessage(format, args...) if(g_verbose) \ jack_error("FreeBoB MSG: " format, ##args ) #define printError(format, args...) jack_error("FreeBoB ERR: " format, ##args ) #define printEnter() #define printExit() #define debugError(format, args...) #define debugPrint(Level, format, args...) #define debugPrintShort(Level, format, args...) #define debugPrintWithTimeStamp(Level, format, args...) #endif // thread priority setup #define FREEBOB_RT_PRIORITY_PACKETIZER_RELATIVE 5 #ifdef FREEBOB_DRIVER_WITH_MIDI #define ALSA_SEQ_BUFF_SIZE 1024 #define MIDI_TRANSMIT_BUFFER_SIZE 1024 #define MIDI_THREAD_SLEEP_TIME_USECS 100 // midi priority should be higher than the audio priority in order to // make sure events are not only delivered on period boundarys // but I think it should be smaller than the packetizer thread in order not // to lose any packets #define FREEBOB_RT_PRIORITY_MIDI_RELATIVE 4 #endif typedef struct _freebob_driver freebob_driver_t; /* * Jack Driver command line parameters */ typedef struct _freebob_jack_settings freebob_jack_settings_t; struct _freebob_jack_settings { int period_size_set; jack_nframes_t period_size; int sample_rate_set; int sample_rate; int buffer_size_set; jack_nframes_t buffer_size; int port_set; int port; int node_id_set; int node_id; int playback_ports; int capture_ports; jack_nframes_t capture_frame_latency; jack_nframes_t playback_frame_latency; freebob_handle_t fb_handle; }; #ifdef FREEBOB_DRIVER_WITH_MIDI typedef struct { int stream_nr; int seq_port_nr; snd_midi_event_t *parser; snd_seq_t *seq_handle; } freebob_midi_port_t; typedef struct _freebob_driver_midi_handle { freebob_device_t *dev; freebob_driver_t *driver; snd_seq_t *seq_handle; pthread_t queue_thread; pthread_t dequeue_thread; int queue_thread_realtime; int queue_thread_priority; int nb_input_ports; int nb_output_ports; freebob_midi_port_t **input_ports; freebob_midi_port_t **output_ports; freebob_midi_port_t **input_stream_port_map; int *output_port_stream_map; } freebob_driver_midi_handle_t; #endif /* * JACK driver structure */ struct _freebob_driver { JACK_DRIVER_NT_DECL jack_nframes_t sample_rate; jack_nframes_t period_size; unsigned long wait_time; jack_time_t wait_last; jack_time_t wait_next; int wait_late; jack_client_t *client; int xrun_detected; int xrun_count; int process_count; /* settings from the command line */ freebob_jack_settings_t settings; /* the freebob virtual device */ freebob_device_t *dev; JSList *capture_ports; JSList *playback_ports; JSList *monitor_ports; unsigned long playback_nchannels; unsigned long capture_nchannels; unsigned long playback_nchannels_audio; unsigned long capture_nchannels_audio; jack_nframes_t playback_frame_latency; jack_nframes_t capture_frame_latency; freebob_device_info_t device_info; freebob_options_t device_options; #ifdef FREEBOB_DRIVER_WITH_MIDI freebob_driver_midi_handle_t *midi_handle; #endif }; #endif /* __JACK_FREEBOB_DRIVER_H__ */ 1.9.12~dfsg/linux/freebob/JackFreebobDriver.cpp0000644000000000000000000011116513214314510020125 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Grame Copyright (C) 2007 Pieter Palmers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "JackFreebobDriver.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackPort.h" #include "JackGraphManager.h" #include "JackLockedEngine.h" namespace Jack { #define jack_get_microseconds GetMicroSeconds #define SAMPLE_MAX_24BIT 8388608.0f #define SAMPLE_MAX_16BIT 32768.0f int JackFreebobDriver::freebob_driver_read (freebob_driver_t * driver, jack_nframes_t nframes) { jack_default_audio_sample_t* buf = NULL; freebob_sample_t nullbuffer[nframes]; void *addr_of_nullbuffer = (void *)nullbuffer; freebob_streaming_stream_type stream_type; printEnter(); // make sure all buffers have a valid buffer if not connected for (unsigned int i = 0; i < driver->capture_nchannels; i++) { stream_type = freebob_streaming_get_playback_stream_type(driver->dev, i); if (stream_type == freebob_stream_type_audio) { freebob_streaming_set_playback_stream_buffer(driver->dev, i, (char *)(nullbuffer), freebob_buffer_type_float); } else if (stream_type == freebob_stream_type_midi) { // these should be read/written with the per-stream functions } else { // empty other buffers without doing something with them freebob_streaming_set_playback_stream_buffer(driver->dev, i, (char *)(nullbuffer), freebob_buffer_type_uint24); } } for (int i = 0; i < fCaptureChannels; i++) { stream_type = freebob_streaming_get_capture_stream_type(driver->dev, i); if (stream_type == freebob_stream_type_audio) { if (fGraphManager->GetConnectionsNum(fCapturePortList[i]) > 0) { buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[i], nframes); if (!buf) { buf = (jack_default_audio_sample_t *)addr_of_nullbuffer; } freebob_streaming_set_capture_stream_buffer(driver->dev, i, (char *)(buf), freebob_buffer_type_float); } } else if (stream_type == freebob_stream_type_midi) { // these should be read/written with the per-stream functions } else { // empty other buffers without doing something with them freebob_streaming_set_capture_stream_buffer(driver->dev, i, (char *)(nullbuffer), freebob_buffer_type_uint24); } } // now transfer the buffers freebob_streaming_transfer_capture_buffers(driver->dev); printExit(); return 0; } int JackFreebobDriver::freebob_driver_write (freebob_driver_t * driver, jack_nframes_t nframes) { jack_default_audio_sample_t* buf = NULL; freebob_streaming_stream_type stream_type; freebob_sample_t nullbuffer[nframes]; void *addr_of_nullbuffer = (void*)nullbuffer; memset(&nullbuffer, 0, nframes*sizeof(freebob_sample_t)); printEnter(); driver->process_count++; assert(driver->dev); // make sure all buffers output silence if not connected for (unsigned int i = 0; i < driver->playback_nchannels; i++) { stream_type = freebob_streaming_get_playback_stream_type(driver->dev, i); if (stream_type == freebob_stream_type_audio) { freebob_streaming_set_playback_stream_buffer(driver->dev, i, (char *)(nullbuffer), freebob_buffer_type_float); } else if (stream_type == freebob_stream_type_midi) { // these should be read/written with the per-stream functions } else { // empty other buffers without doing something with them freebob_streaming_set_playback_stream_buffer(driver->dev, i, (char *)(nullbuffer), freebob_buffer_type_uint24); } } for (int i = 0; i < fPlaybackChannels; i++) { stream_type = freebob_streaming_get_playback_stream_type(driver->dev, i); if (stream_type == freebob_stream_type_audio) { // Ouput ports if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[i], nframes); if (!buf) { buf = (jack_default_audio_sample_t *)addr_of_nullbuffer; } freebob_streaming_set_playback_stream_buffer(driver->dev, i, (char *)(buf), freebob_buffer_type_float); } } } freebob_streaming_transfer_playback_buffers(driver->dev); printExit(); return 0; } jack_nframes_t JackFreebobDriver::freebob_driver_wait (freebob_driver_t *driver, int extra_fd, int *status, float *delayed_usecs) { int nframes; jack_time_t wait_enter; jack_time_t wait_ret; printEnter(); wait_enter = jack_get_microseconds (); if (wait_enter > driver->wait_next) { /* * This processing cycle was delayed past the * next due interrupt! Do not account this as * a wakeup delay: */ driver->wait_next = 0; driver->wait_late++; } // *status = -2; interrupt // *status = -3; timeout // *status = -4; extra FD nframes = freebob_streaming_wait(driver->dev); wait_ret = jack_get_microseconds (); if (driver->wait_next && wait_ret > driver->wait_next) { *delayed_usecs = wait_ret - driver->wait_next; } driver->wait_last = wait_ret; driver->wait_next = wait_ret + driver->period_usecs; // driver->engine->transport_cycle_start (driver->engine, wait_ret); if (nframes < 0) { *status = 0; return 0; } *status = 0; fBeginDateUst = wait_ret; // FIXME: this should do something more usefull *delayed_usecs = 0; printExit(); return nframes - nframes % driver->period_size; } int JackFreebobDriver::freebob_driver_start (freebob_driver_t *driver) { int retval = 0; #ifdef FREEBOB_DRIVER_WITH_MIDI if (driver->midi_handle) { if ((retval = freebob_driver_midi_start(driver->midi_handle))) { printError("Could not start MIDI threads"); return retval; } } #endif if ((retval = freebob_streaming_start(driver->dev))) { printError("Could not start streaming threads"); #ifdef FREEBOB_DRIVER_WITH_MIDI if (driver->midi_handle) { freebob_driver_midi_stop(driver->midi_handle); } #endif return retval; } return 0; } int JackFreebobDriver::freebob_driver_stop (freebob_driver_t *driver) { int retval = 0; #ifdef FREEBOB_DRIVER_WITH_MIDI if (driver->midi_handle) { if ((retval = freebob_driver_midi_stop(driver->midi_handle))) { printError("Could not stop MIDI threads"); return retval; } } #endif if ((retval = freebob_streaming_stop(driver->dev))) { printError("Could not stop streaming threads"); return retval; } return 0; } int JackFreebobDriver::freebob_driver_restart (freebob_driver_t *driver) { if (Stop()) return -1; return Start(); } int JackFreebobDriver::SetBufferSize (jack_nframes_t nframes) { printError("Buffer size change requested but not supported!!!"); /* driver->period_size = nframes; driver->period_usecs = (jack_time_t) floor ((((float) nframes) / driver->sample_rate) * 1000000.0f); */ /* tell the engine to change its buffer size */ //driver->engine->set_buffer_size (driver->engine, nframes); return -1; // unsupported } typedef void (*JackDriverFinishFunction) (jack_driver_t *); freebob_driver_t * JackFreebobDriver::freebob_driver_new (char *name, freebob_jack_settings_t *params) { freebob_driver_t *driver; assert(params); if (freebob_get_api_version() != 1) { printMessage("Incompatible libfreebob version! (%s)", freebob_get_version()); return NULL; } printMessage("Starting Freebob backend (%s)", freebob_get_version()); driver = (freebob_driver_t*)calloc (1, sizeof (freebob_driver_t)); /* Setup the jack interfaces */ jack_driver_nt_init ((jack_driver_nt_t *) driver); /* driver->nt_attach = (JackDriverNTAttachFunction) freebob_driver_attach; driver->nt_detach = (JackDriverNTDetachFunction) freebob_driver_detach; driver->nt_start = (JackDriverNTStartFunction) freebob_driver_start; driver->nt_stop = (JackDriverNTStopFunction) freebob_driver_stop; driver->nt_run_cycle = (JackDriverNTRunCycleFunction) freebob_driver_run_cycle; driver->null_cycle = (JackDriverNullCycleFunction) freebob_driver_null_cycle; driver->write = (JackDriverReadFunction) freebob_driver_write; driver->read = (JackDriverReadFunction) freebob_driver_read; driver->nt_bufsize = (JackDriverNTBufSizeFunction) freebob_driver_bufsize; */ /* copy command line parameter contents to the driver structure */ memcpy(&driver->settings, params, sizeof(freebob_jack_settings_t)); /* prepare all parameters */ driver->sample_rate = params->sample_rate; driver->period_size = params->period_size; fBeginDateUst = 0; driver->period_usecs = (jack_time_t) floor ((((float) driver->period_size) * 1000000.0f) / driver->sample_rate); // driver->client = client; driver->engine = NULL; memset(&driver->device_options, 0, sizeof(driver->device_options)); driver->device_options.sample_rate = params->sample_rate; driver->device_options.period_size = params->period_size; driver->device_options.nb_buffers = params->buffer_size; driver->device_options.node_id = params->node_id; driver->device_options.port = params->port; driver->capture_frame_latency = params->capture_frame_latency; driver->playback_frame_latency = params->playback_frame_latency; if (!params->capture_ports) { driver->device_options.directions |= FREEBOB_IGNORE_CAPTURE; } if (!params->playback_ports) { driver->device_options.directions |= FREEBOB_IGNORE_PLAYBACK; } debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s", __DATE__, __TIME__); debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name); debugPrint(DEBUG_LEVEL_STARTUP, " period_size: %d", driver->period_size); debugPrint(DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs); debugPrint(DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->sample_rate); return (freebob_driver_t *) driver; } void JackFreebobDriver::freebob_driver_delete (freebob_driver_t *driver) { free (driver); } #ifdef FREEBOB_DRIVER_WITH_MIDI /* * MIDI support */ // the thread that will queue the midi events from the seq to the stream buffers void * JackFreebobDriver::freebob_driver_midi_queue_thread(void *arg) { freebob_driver_midi_handle_t *m = (freebob_driver_midi_handle_t *)arg; assert(m); snd_seq_event_t *ev; unsigned char work_buffer[MIDI_TRANSMIT_BUFFER_SIZE]; int bytes_to_send; int b; int i; printMessage("MIDI queue thread started"); while (1) { // get next event, if one is present while ((snd_seq_event_input(m->seq_handle, &ev) > 0)) { // get the port this event is originated from freebob_midi_port_t *port = NULL; for (i = 0;i < m->nb_output_ports;i++) { if (m->output_ports[i]->seq_port_nr == ev->dest.port) { port = m->output_ports[i]; break; } } if (!port) { printError(" Could not find target port for event: dst=%d src=%d", ev->dest.port, ev->source.port); break; } // decode it to the work buffer if ((bytes_to_send = snd_midi_event_decode ( port->parser, work_buffer, MIDI_TRANSMIT_BUFFER_SIZE, ev)) < 0) { // failed printError(" Error decoding event for port %d (errcode=%d)", port->seq_port_nr, bytes_to_send); bytes_to_send = 0; //return -1; } for (b = 0;b < bytes_to_send;b++) { freebob_sample_t tmp_event = work_buffer[b]; if (freebob_streaming_write(m->dev, port->stream_nr, &tmp_event, 1) < 1) { printError(" Midi send buffer overrun"); } } } // sleep for some time usleep(MIDI_THREAD_SLEEP_TIME_USECS); } return NULL; } // the dequeue thread (maybe we need one thread per stream) void * JackFreebobDriver::freebob_driver_midi_dequeue_thread (void *arg) { freebob_driver_midi_handle_t *m = (freebob_driver_midi_handle_t *)arg; int i; int s; int samples_read; assert(m); while (1) { // read incoming events for (i = 0;i < m->nb_input_ports;i++) { unsigned int buff[64]; freebob_midi_port_t *port = m->input_ports[i]; if (!port) { printError(" something went wrong when setting up the midi input port map (%d)", i); } do { samples_read = freebob_streaming_read(m->dev, port->stream_nr, buff, 64); for (s = 0;s < samples_read;s++) { unsigned int *byte = (buff + s) ; snd_seq_event_t ev; if ((snd_midi_event_encode_byte(port->parser, (*byte) & 0xFF, &ev)) > 0) { // a midi message is complete, send it out to ALSA snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); snd_seq_ev_set_source(&ev, port->seq_port_nr); snd_seq_event_output_direct(port->seq_handle, &ev); } } } while (samples_read > 0); } // sleep for some time usleep(MIDI_THREAD_SLEEP_TIME_USECS); } return NULL; } freebob_driver_midi_handle_t * JackFreebobDriver::freebob_driver_midi_init(freebob_driver_t *driver) { char buf[256]; channel_t chn; int nchannels; int i = 0; freebob_device_t *dev = driver->dev; assert(dev); freebob_driver_midi_handle_t *m = calloc(1, sizeof(freebob_driver_midi_handle_t)); if (!m) { printError("not enough memory to create midi structure"); return NULL; } if (snd_seq_open(&m->seq_handle, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK) < 0) { printError("Error opening ALSA sequencer."); free(m); return NULL; } snd_seq_set_client_name(m->seq_handle, "FreeBoB Jack MIDI"); // find out the number of midi in/out ports we need to setup nchannels = freebob_streaming_get_nb_capture_streams(dev); m->nb_input_ports = 0; for (chn = 0; chn < nchannels; chn++) { if (freebob_streaming_get_capture_stream_type(dev, chn) == freebob_stream_type_midi) { m->nb_input_ports++; } } m->input_ports = calloc(m->nb_input_ports, sizeof(freebob_midi_port_t *)); if (!m->input_ports) { printError("not enough memory to create midi structure"); free(m); return NULL; } i = 0; for (chn = 0; chn < nchannels; chn++) { if (freebob_streaming_get_capture_stream_type(dev, chn) == freebob_stream_type_midi) { m->input_ports[i] = calloc(1, sizeof(freebob_midi_port_t)); if (!m->input_ports[i]) { // fixme printError("Could not allocate memory for seq port"); continue; } freebob_streaming_get_capture_stream_name(dev, chn, buf, sizeof(buf)); printMessage("Register MIDI IN port %s", buf); m->input_ports[i]->seq_port_nr = snd_seq_create_simple_port(m->seq_handle, buf, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC); if (m->input_ports[i]->seq_port_nr < 0) { printError("Could not create seq port"); m->input_ports[i]->stream_nr = -1; m->input_ports[i]->seq_port_nr = -1; } else { m->input_ports[i]->stream_nr = chn; m->input_ports[i]->seq_handle = m->seq_handle; if (snd_midi_event_new ( ALSA_SEQ_BUFF_SIZE, &(m->input_ports[i]->parser)) < 0) { printError("could not init parser for MIDI IN port %d", i); m->input_ports[i]->stream_nr = -1; m->input_ports[i]->seq_port_nr = -1; } } i++; } } // playback nchannels = freebob_streaming_get_nb_playback_streams(dev); m->nb_output_ports = 0; for (chn = 0; chn < nchannels; chn++) { if (freebob_streaming_get_playback_stream_type(dev, chn) == freebob_stream_type_midi) { m->nb_output_ports++; } } m->output_ports = calloc(m->nb_output_ports, sizeof(freebob_midi_port_t *)); if (!m->output_ports) { printError("not enough memory to create midi structure"); for (i = 0; i < m->nb_input_ports; i++) { free(m->input_ports[i]); } free(m->input_ports); free(m); return NULL; } i = 0; for (chn = 0; chn < nchannels; chn++) { if (freebob_streaming_get_playback_stream_type(dev, chn) == freebob_stream_type_midi) { m->output_ports[i] = calloc(1, sizeof(freebob_midi_port_t)); if (!m->output_ports[i]) { // fixme printError("Could not allocate memory for seq port"); continue; } freebob_streaming_get_playback_stream_name(dev, chn, buf, sizeof(buf)); printMessage("Register MIDI OUT port %s", buf); m->output_ports[i]->seq_port_nr = snd_seq_create_simple_port(m->seq_handle, buf, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC); if (m->output_ports[i]->seq_port_nr < 0) { printError("Could not create seq port"); m->output_ports[i]->stream_nr = -1; m->output_ports[i]->seq_port_nr = -1; } else { m->output_ports[i]->stream_nr = chn; m->output_ports[i]->seq_handle = m->seq_handle; if (snd_midi_event_new ( ALSA_SEQ_BUFF_SIZE, &(m->output_ports[i]->parser)) < 0) { printError("could not init parser for MIDI OUT port %d", i); m->output_ports[i]->stream_nr = -1; m->output_ports[i]->seq_port_nr = -1; } } i++; } } m->dev = dev; m->driver = driver; return m; } int JackFreebobDriver::freebob_driver_midi_start (freebob_driver_midi_handle_t *m) { assert(m); // start threads m->queue_thread_realtime = (m->driver->engine->control->real_time ? 1 : 0); m->queue_thread_priority = m->driver->engine->control->client_priority + FREEBOB_RT_PRIORITY_MIDI_RELATIVE; if (m->queue_thread_priority > 98) { m->queue_thread_priority = 98; } if (m->queue_thread_realtime) { printMessage("MIDI threads running with Realtime scheduling, priority %d", m->queue_thread_priority); } else { printMessage("MIDI threads running without Realtime scheduling"); } if (jack_client_create_thread(NULL, &m->queue_thread, m->queue_thread_priority, m->queue_thread_realtime, freebob_driver_midi_queue_thread, (void *)m)) { printError(" cannot create midi queueing thread"); return -1; } if (jack_client_create_thread(NULL, &m->dequeue_thread, m->queue_thread_priority, m->queue_thread_realtime, freebob_driver_midi_dequeue_thread, (void *)m)) { printError(" cannot create midi dequeueing thread"); return -1; } return 0; } int JackFreebobDriver::freebob_driver_midi_stop (freebob_driver_midi_handle_t *m) { assert(m); pthread_cancel (m->queue_thread); pthread_join (m->queue_thread, NULL); pthread_cancel (m->dequeue_thread); pthread_join (m->dequeue_thread, NULL); return 0; } void JackFreebobDriver::freebob_driver_midi_finish (freebob_driver_midi_handle_t *m) { assert(m); int i; // TODO: add state info here, if not stopped then stop for (i = 0;i < m->nb_input_ports;i++) { free(m->input_ports[i]); } free(m->input_ports); for (i = 0;i < m->nb_output_ports;i++) { free(m->output_ports[i]); } free(m->output_ports); free(m); } #endif int JackFreebobDriver::Attach() { JackPort* port; jack_port_id_t port_index; char buf[REAL_JACK_PORT_NAME_SIZE]; char portname[REAL_JACK_PORT_NAME_SIZE]; jack_latency_range_t range; freebob_driver_t* driver = (freebob_driver_t*)fDriver; jack_log("JackFreebobDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); g_verbose = (fEngineControl->fVerbose ? 1 : 0); driver->device_options.verbose = (fEngineControl->fVerbose ? 1 : 0); /* packetizer thread options */ driver->device_options.realtime = (fEngineControl->fRealTime ? 1 : 0); driver->device_options.packetizer_priority = fEngineControl->fServerPriority + FREEBOB_RT_PRIORITY_PACKETIZER_RELATIVE; if (driver->device_options.packetizer_priority > 98) { driver->device_options.packetizer_priority = 98; } // initialize the thread driver->dev = freebob_streaming_init(&driver->device_info, driver->device_options); if (!driver->dev) { printError("FREEBOB: Error creating virtual device"); return -1; } #ifdef FREEBOB_DRIVER_WITH_MIDI driver->midi_handle = freebob_driver_midi_init(driver); if (!driver->midi_handle) { printError("-----------------------------------------------------------"); printError("Error creating midi device!"); printError("FreeBob will run without MIDI support."); printError("Consult the above error messages to solve the problem. "); printError("-----------------------------------------------------------\n\n"); } #endif if (driver->device_options.realtime) { printMessage("Streaming thread running with Realtime scheduling, priority %d", driver->device_options.packetizer_priority); } else { printMessage("Streaming thread running without Realtime scheduling"); } /* ports */ // capture driver->capture_nchannels = freebob_streaming_get_nb_capture_streams(driver->dev); driver->capture_nchannels_audio = 0; for (unsigned int i = 0; i < driver->capture_nchannels; i++) { freebob_streaming_get_capture_stream_name(driver->dev, i, portname, sizeof(portname)); snprintf(buf, sizeof(buf), "%s:%s", fClientControl.fName, portname); if (freebob_streaming_get_capture_stream_type(driver->dev, i) != freebob_stream_type_audio) { printMessage ("Don't register capture port %s", buf); } else { printMessage ("Registering capture port %s", buf); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } port = fGraphManager->GetPort(port_index); range.min = range.max = driver->period_size + driver->capture_frame_latency; port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackFreebobDriver::Attach fCapturePortList[i] %ld ", port_index); driver->capture_nchannels_audio++; } } // playback driver->playback_nchannels = freebob_streaming_get_nb_playback_streams(driver->dev); driver->playback_nchannels_audio = 0; for (unsigned int i = 0; i < driver->playback_nchannels; i++) { freebob_streaming_get_playback_stream_name(driver->dev, i, portname, sizeof(portname)); snprintf(buf, sizeof(buf), "%s:%s", fClientControl.fName, portname); if (freebob_streaming_get_playback_stream_type(driver->dev, i) != freebob_stream_type_audio) { printMessage ("Don't register playback port %s", buf); } else { printMessage ("Registering playback port %s", buf); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency; port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackFreebobDriver::Attach fPlaybackPortList[i] %ld ", port_index); driver->playback_nchannels_audio++; } } fCaptureChannels = driver->capture_nchannels_audio; fPlaybackChannels = driver->playback_nchannels_audio; assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); // this makes no sense... assert(fCaptureChannels + fPlaybackChannels > 0); return 0; } int JackFreebobDriver::Detach() { freebob_driver_t* driver = (freebob_driver_t*)fDriver; jack_log("JackFreebobDriver::Detach"); // finish the libfreebob streaming freebob_streaming_finish(driver->dev); driver->dev = NULL; #ifdef FREEBOB_DRIVER_WITH_MIDI if (driver->midi_handle) { freebob_driver_midi_finish(driver->midi_handle); } driver->midi_handle = NULL; #endif return JackAudioDriver::Detach(); // Generic JackAudioDriver Detach } int JackFreebobDriver::Open(freebob_jack_settings_t *params) { // Generic JackAudioDriver Open if (JackAudioDriver::Open( params->period_size, params->sample_rate, params->playback_ports, params->playback_ports, 0, 0, 0, "", "", params->capture_frame_latency, params->playback_frame_latency) != 0) { return -1; } fDriver = (jack_driver_t *)freebob_driver_new ((char*)"freebob_pcm", params); if (fDriver) { // FreeBoB driver may have changed the in/out values fCaptureChannels = ((freebob_driver_t *)fDriver)->capture_nchannels_audio; fPlaybackChannels = ((freebob_driver_t *)fDriver)->playback_nchannels_audio; return 0; } else { JackAudioDriver::Close(); return -1; } } int JackFreebobDriver::Close() { // Generic audio driver close int res = JackAudioDriver::Close(); freebob_driver_delete((freebob_driver_t*)fDriver); return res; } int JackFreebobDriver::Start() { int res = JackAudioDriver::Start(); if (res >= 0) { res = freebob_driver_start((freebob_driver_t *)fDriver); if (res < 0) { JackAudioDriver::Stop(); } } return res; } int JackFreebobDriver::Stop() { int res = freebob_driver_stop((freebob_driver_t *)fDriver); if (JackAudioDriver::Stop() < 0) { res = -1; } return res; } int JackFreebobDriver::Read() { printEnter(); /* Taken from freebob_driver_run_cycle */ freebob_driver_t* driver = (freebob_driver_t*)fDriver; int wait_status = 0; fDelayedUsecs = 0.f; retry: jack_nframes_t nframes = freebob_driver_wait (driver, -1, &wait_status, &fDelayedUsecs); if ((wait_status < 0)) { printError( "wait status < 0! (= %d)", wait_status); return -1; } if (nframes == 0) { /* we detected an xrun and restarted: notify * clients about the delay. */ jack_log("FreeBoB XRun"); NotifyXRun(fBeginDateUst, fDelayedUsecs); goto retry; /* recoverable error*/ } if (nframes != fEngineControl->fBufferSize) jack_log("JackFreebobDriver::Read warning nframes = %ld", nframes); // Has to be done before read JackDriver::CycleIncTime(); printExit(); return freebob_driver_read((freebob_driver_t *)fDriver, fEngineControl->fBufferSize); } int JackFreebobDriver::Write() { printEnter(); int res = freebob_driver_write((freebob_driver_t *)fDriver, fEngineControl->fBufferSize); printExit(); return res; } void JackFreebobDriver::jack_driver_init (jack_driver_t *driver) { memset (driver, 0, sizeof (*driver)); driver->attach = 0; driver->detach = 0; driver->write = 0; driver->read = 0; driver->null_cycle = 0; driver->bufsize = 0; driver->start = 0; driver->stop = 0; } void JackFreebobDriver::jack_driver_nt_init (jack_driver_nt_t * driver) { memset (driver, 0, sizeof (*driver)); jack_driver_init ((jack_driver_t *) driver); driver->attach = 0; driver->detach = 0; driver->bufsize = 0; driver->stop = 0; driver->start = 0; driver->nt_bufsize = 0; driver->nt_start = 0; driver->nt_stop = 0; driver->nt_attach = 0; driver->nt_detach = 0; driver->nt_run_cycle = 0; } } // end of namespace #ifdef __cplusplus extern "C" { #endif const jack_driver_desc_t * driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("freebob", JackDriverMaster, "Linux FreeBob API based audio backend", &filler); strcpy(value.str, "hw:0"); jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "The FireWire device to use. Format is: 'hw:port[,node]'.", NULL); value.ui = 1024; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = 3; jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods of playback latency", NULL); value.ui = 48000U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamBool, &value, NULL, "Provide capture ports.", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamBool, &value, NULL, "Provide playback ports.", NULL); value.i = 1; jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports.", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency (frames)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency (frames)", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Number of input channels to provide (note: currently ignored)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Number of output channels to provide (note: currently ignored)", NULL); return desc; } Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { unsigned int port = 0; unsigned int node_id = -1; int nbitems; const JSList * node; const jack_driver_param_t * param; freebob_jack_settings_t cmlparams; const char *device_name = "hw:0"; cmlparams.period_size_set = 0; cmlparams.sample_rate_set = 0; cmlparams.buffer_size_set = 0; cmlparams.port_set = 0; cmlparams.node_id_set = 0; /* default values */ cmlparams.period_size = 1024; cmlparams.sample_rate = 48000; cmlparams.buffer_size = 3; cmlparams.port = 0; cmlparams.node_id = -1; cmlparams.playback_ports = 0; cmlparams.capture_ports = 0; cmlparams.playback_frame_latency = 0; cmlparams.capture_frame_latency = 0; for (node = params; node; node = jack_slist_next (node)) { param = (jack_driver_param_t *) node->data; switch (param->character) { case 'd': device_name = param->value.str; break; case 'p': cmlparams.period_size = param->value.ui; cmlparams.period_size_set = 1; break; case 'n': cmlparams.buffer_size = param->value.ui; cmlparams.buffer_size_set = 1; break; case 'r': cmlparams.sample_rate = param->value.ui; cmlparams.sample_rate_set = 1; break; case 'C': cmlparams.capture_ports = 1; break; case 'P': cmlparams.playback_ports = 1; break; case 'D': cmlparams.capture_ports = 1; cmlparams.playback_ports = 1; break; case 'I': cmlparams.capture_frame_latency = param->value.ui; break; case 'O': cmlparams.playback_frame_latency = param->value.ui; break; // ignore these for now case 'i': break; case 'o': break; } } /* duplex is the default */ if (!cmlparams.playback_ports && !cmlparams.capture_ports) { cmlparams.playback_ports = TRUE; cmlparams.capture_ports = TRUE; } nbitems = sscanf(device_name, "hw:%u,%u", &port, &node_id); if (nbitems < 2) { nbitems = sscanf(device_name, "hw:%u", &port); if (nbitems < 1) { printError("device (-d) argument not valid\n"); return NULL; } else { cmlparams.port = port; cmlparams.port_set = 1; cmlparams.node_id = -1; cmlparams.node_id_set = 0; } } else { cmlparams.port = port; cmlparams.port_set = 1; cmlparams.node_id = node_id; cmlparams.node_id_set = 1; } jack_error("Freebob using Firewire port %d, node %d", cmlparams.port, cmlparams.node_id); Jack::JackFreebobDriver* freebob_driver = new Jack::JackFreebobDriver("system", "freebob_pcm", engine, table); Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(freebob_driver); // Special open for FreeBoB driver... if (freebob_driver->Open(&cmlparams) == 0) { return threaded_driver; } else { delete threaded_driver; // Delete the decorated driver return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/linux/freebob/JackFreebobDriver.h0000644000000000000000000000564613214314510017600 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Grame Copyright (C) 2007 Pieter Palmers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackFreebobDriver__ #define __JackFreebobDriver__ #include "JackAudioDriver.h" #include "JackThreadedDriver.h" #include "JackTime.h" #include "freebob_driver.h" namespace Jack { /*! \brief The FreeBoB driver. */ class JackFreebobDriver : public JackAudioDriver { private: // enable verbose messages int g_verbose; jack_driver_t* fDriver; int freebob_driver_attach (freebob_driver_t *driver); int freebob_driver_detach (freebob_driver_t *driver); int freebob_driver_read (freebob_driver_t * driver, jack_nframes_t nframes); int freebob_driver_write (freebob_driver_t * driver, jack_nframes_t nframes); jack_nframes_t freebob_driver_wait (freebob_driver_t *driver, int extra_fd, int *status, float *delayed_usecs); int freebob_driver_start (freebob_driver_t *driver); int freebob_driver_stop (freebob_driver_t *driver); int freebob_driver_restart (freebob_driver_t *driver); freebob_driver_t *freebob_driver_new (char *name, freebob_jack_settings_t *params); void freebob_driver_delete (freebob_driver_t *driver); #ifdef FREEBOB_DRIVER_WITH_MIDI freebob_driver_midi_handle_t *freebob_driver_midi_init(freebob_driver_t *driver); void freebob_driver_midi_finish (freebob_driver_midi_handle_t *m); int freebob_driver_midi_start (freebob_driver_midi_handle_t *m); int freebob_driver_midi_stop (freebob_driver_midi_handle_t *m); #endif void jack_driver_init (jack_driver_t *driver); void jack_driver_nt_init (jack_driver_nt_t * driver); public: JackFreebobDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) :JackAudioDriver(name, alias, engine, table) {} virtual ~JackFreebobDriver() {} int Open(freebob_jack_settings_t *cmlparams); int Close(); int Attach(); int Detach(); int Start(); int Stop(); int Read(); int Write(); int SetBufferSize(jack_nframes_t nframes); }; } // end of namespace #endif 1.9.12~dfsg/linux/JackLinuxTime.c0000644000000000000000000001230213214314510015350 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2005 Jussi Laako Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackConstants.h" #include "JackTime.h" #include "JackTypes.h" #include "JackError.h" #include #include #include #include #include #include #include #include #include #include #include #include jack_time_t (*_jack_get_microseconds)(void) = 0; #if defined(__gnu_linux__) && (defined(__i386__) || defined(__x86_64__)) #define HPET_SUPPORT #define HPET_MMAP_SIZE 1024 #define HPET_CAPS 0x000 #define HPET_PERIOD 0x004 #define HPET_COUNTER 0x0f0 #define HPET_CAPS_COUNTER_64BIT (1 << 13) #if defined(__x86_64__) typedef uint64_t hpet_counter_t; #else typedef uint32_t hpet_counter_t; #endif static int hpet_fd; static unsigned char *hpet_ptr; static uint32_t hpet_period; /* period length in femto secs */ static uint64_t hpet_offset = 0; static uint64_t hpet_wrap; static hpet_counter_t hpet_previous = 0; #endif /* defined(__gnu_linux__) && (__i386__ || __x86_64__) */ #ifdef HPET_SUPPORT static int jack_hpet_init () { uint32_t hpet_caps; hpet_fd = open("/dev/hpet", O_RDONLY); if (hpet_fd < 0) { jack_error ("This system has no accessible HPET device (%s)", strerror (errno)); return -1; } hpet_ptr = (unsigned char *) mmap(NULL, HPET_MMAP_SIZE, PROT_READ, MAP_SHARED, hpet_fd, 0); if (hpet_ptr == MAP_FAILED) { jack_error ("This system has no mappable HPET device (%s)", strerror (errno)); close (hpet_fd); return -1; } /* this assumes period to be constant. if needed, it can be moved to the clock access function */ hpet_period = *((uint32_t *) (hpet_ptr + HPET_PERIOD)); hpet_caps = *((uint32_t *) (hpet_ptr + HPET_CAPS)); hpet_wrap = ((hpet_caps & HPET_CAPS_COUNTER_64BIT) && (sizeof(hpet_counter_t) == sizeof(uint64_t))) ? 0 : ((uint64_t) 1 << 32); return 0; } static jack_time_t jack_get_microseconds_from_hpet (void) { hpet_counter_t hpet_counter; long double hpet_time; hpet_counter = *((hpet_counter_t *) (hpet_ptr + HPET_COUNTER)); if (hpet_counter < hpet_previous) hpet_offset += hpet_wrap; hpet_previous = hpet_counter; hpet_time = (long double) (hpet_offset + hpet_counter) * (long double) hpet_period * (long double) 1e-9; return ((jack_time_t) (hpet_time + 0.5)); } #else static int jack_hpet_init () { jack_error ("This version of JACK or this computer does not have HPET support.\n" "Please choose a different clock source."); return -1; } static jack_time_t jack_get_microseconds_from_hpet (void) { /* never called */ return 0; } #endif /* HPET_SUPPORT */ #define HAVE_CLOCK_GETTIME 1 #ifndef HAVE_CLOCK_GETTIME static jack_time_t jack_get_microseconds_from_system (void) { jack_time_t jackTime; struct timeval tv; gettimeofday (&tv, NULL); jackTime = (jack_time_t) tv.tv_sec * 1000000 + (jack_time_t) tv.tv_usec; return jackTime; } #else static jack_time_t jack_get_microseconds_from_system (void) { jack_time_t jackTime; struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time); jackTime = (jack_time_t) time.tv_sec * 1e6 + (jack_time_t) time.tv_nsec / 1e3; return jackTime; } #endif /* HAVE_CLOCK_GETTIME */ SERVER_EXPORT void JackSleep(long usec) { usleep(usec); } SERVER_EXPORT void InitTime() { /* nothing to do on a generic system - we use the system clock */ } SERVER_EXPORT void EndTime() {} void SetClockSource(jack_timer_type_t source) { jack_log("Clock source : %s", ClockSourceName(source)); switch (source) { case JACK_TIMER_HPET: if (jack_hpet_init () == 0) { _jack_get_microseconds = jack_get_microseconds_from_hpet; } else { _jack_get_microseconds = jack_get_microseconds_from_system; } break; case JACK_TIMER_SYSTEM_CLOCK: default: _jack_get_microseconds = jack_get_microseconds_from_system; break; } } const char* ClockSourceName(jack_timer_type_t source) { switch (source) { case JACK_TIMER_HPET: return "hpet"; case JACK_TIMER_SYSTEM_CLOCK: #ifdef HAVE_CLOCK_GETTIME return "system clock via clock_gettime"; #else return "system clock via gettimeofday"; #endif } /* what is wrong with gcc ? */ return "unknown"; } SERVER_EXPORT jack_time_t GetMicroSeconds() { return _jack_get_microseconds(); } SERVER_EXPORT jack_time_t jack_get_microseconds() { return _jack_get_microseconds(); } 1.9.12~dfsg/jack.pc.in0000644000000000000000000000044713214314510013206 0ustar rootrootprefix=@PREFIX@ exec_prefix=@PREFIX@ libdir=@LIBDIR@ includedir=@INCLUDEDIR@ server_libs=-L@LIBDIR@ -l@SERVERLIB@ Name: jack Description: the Jack Audio Connection Kit: a low-latency synchronous callback-based media server Version: @JACK_VERSION@ Libs: -L@LIBDIR@ -ljack Cflags: -I@INCLUDEDIR@ 1.9.12~dfsg/.gitignore0000644000000000000000000000012513214314510013326 0ustar rootrootbuild/ man/*.1 .lock* __pycache__ *.pyc android/.server/ android/.client/ codeBlocks 1.9.12~dfsg/android/0000755000000000000000000000000013214314510012760 5ustar rootroot1.9.12~dfsg/android/BpAndroidShm.cpp0000644000000000000000000000753713214314510016012 0ustar rootroot#include #include #include "BpAndroidShm.h" namespace android{ int BpAndroidShm::sendCommand(const char*command) { Parcel data, reply; data.writeInterfaceToken( IAndroidShm::getInterfaceDescriptor()); data.writeCString(command); status_t status = remote()->transact(HW_SENDCOMMAND, data, &reply); if(status != NO_ERROR) { ALOGE("print sendCommand error: %s", strerror(-status)); } else { status= reply.readInt32(); } return status; } sp BpAndroidShm::getBuffer(int index) { Parcel data, reply; sp memHeap = NULL; data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor()); data.writeInt32(index); remote()->transact(HW_GETBUFFER, data, &reply); memHeap = interface_cast (reply.readStrongBinder()); return memHeap; } BpAndroidShm::BpAndroidShm( const sp& impl) : BpInterface(impl) {} BpAndroidShm::~BpAndroidShm() {} int BpAndroidShm::allocShm(const int size) { // if negative return value is error Parcel data, reply; data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor()); data.writeInt32(size); status_t status = remote()->transact(HW_ALLOC_SHM, data, &reply); if(status != NO_ERROR) { ALOGE("print allocShm error: %s", strerror(-status)); } else { status= reply.readInt32(); } return status; } int BpAndroidShm::removeShm(const unsigned int index) { // shared memory Á¦°Å Parcel data, reply; data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor()); data.writeInt32(index); status_t status = remote()->transact(HW_REMOVE_SHM, data, &reply); if(status != NO_ERROR) { ALOGE("print removeShm error: %s", strerror(-status)); } else { status= reply.readInt32(); } return status; } int BpAndroidShm::isAllocated(const unsigned int index) { // allocated ¿©ºÎ È®ÀÎ Parcel data, reply; data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor()); data.writeInt32(index); status_t status = remote()->transact(HW_IS_ALLOCATED, data, &reply); if(status != NO_ERROR) { ALOGE("print isAllocated error: %s", strerror(-status)); } else { status= reply.readInt32(); } return status; } int BpAndroidShm::setRegistryIndex(const unsigned int index) { Parcel data, reply; data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor()); data.writeInt32(index); status_t status = remote()->transact(HW_SET_REGISTRY_INDEX, data, &reply); if(status != NO_ERROR) { ALOGE("print setRegistryIndex error: %s", strerror(-status)); } else { status= reply.readInt32(); } return status; } int BpAndroidShm::getRegistryIndex() { Parcel data, reply; data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor()); status_t status = remote()->transact(HW_GET_REGISTRY_INDEX, data, &reply); if(status != NO_ERROR) { ALOGE("print getRegistryIndex error: %s", strerror(-status)); } else { status= reply.readInt32(); } return status; } sp BpAndroidShm::InitSemaphore(const char* name) { Parcel data, reply; sp memHeap = NULL; data.writeInterfaceToken(IAndroidShm::getInterfaceDescriptor()); data.writeCString(name); status_t status = remote()->transact(HW_INIT_SEMAPHORE, data, &reply); memHeap = interface_cast (reply.readStrongBinder()); return memHeap; } }; 1.9.12~dfsg/android/BpAndroidShm.h0000644000000000000000000000141313214314510015442 0ustar rootroot#ifndef BPANDROIDSHM #define BPANDROIDSHM #include #include "IAndroidShm.h" #include namespace android { class BpAndroidShm: public BpInterface { public: BpAndroidShm( const sp & impl); virtual ~BpAndroidShm(); virtual sp getBuffer(int index); virtual int sendCommand(const char *command); virtual int allocShm(const int size); // if negative return value is error virtual int removeShm(const unsigned int index); // shared memory Á¦°Å virtual int isAllocated(const unsigned int index); // allocated ¿©ºÎ È®ÀÎ virtual int setRegistryIndex(const unsigned int index); virtual int getRegistryIndex(); virtual sp InitSemaphore(const char* name); }; }; #endif 1.9.12~dfsg/android/cxx-stl/0000755000000000000000000000000013214314510014362 5ustar rootroot1.9.12~dfsg/android/cxx-stl/gnu-libstdc++/0000755000000000000000000000000013214314510016723 5ustar rootroot1.9.12~dfsg/android/cxx-stl/gnu-libstdc++/libs/0000755000000000000000000000000013214314510017654 5ustar rootroot1.9.12~dfsg/android/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/0000755000000000000000000000000013214314510021747 5ustar rootroot1.9.12~dfsg/android/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/0000755000000000000000000000000013214314510023372 5ustar rootroot1.9.12~dfsg/android/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/bits/0000755000000000000000000000000013214314510024333 5ustar rootroot1.9.12~dfsg/android/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/bits/ctype_base.h0000644000000000000000000000051313214314510026621 0ustar rootroot //fix build error in KitKat #define _U _CTYPE_U #define _L _CTYPE_L #define _N _CTYPE_N #define _S _CTYPE_S #define _P _CTYPE_P #define _C _CTYPE_C #define _X _CTYPE_X #define _B _CTYPE_B #include <../../../../../../../../../../../prebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/bits/ctype_base.h> 1.9.12~dfsg/android/JackShmMem_os.h0000644000000000000000000000254113214314510015613 0ustar rootroot/* Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackShmMem__android__ #define __JackShmMem__android__ #include #include #define CHECK_MLOCK(ptr, size) (mlock((ptr), (size)) == 0) #define CHECK_MUNLOCK(ptr, size) (munlock((ptr), (size)) == 0) #define CHECK_MLOCKALL() (false) #define CHECK_MUNLOCKALL() (false) /* fix for crash jack server issue: * case 1) jack_destroy_shm() in JackShmReadWritePtr1::Init() causes crash * because server lost shared memory by destroying client side ahead. */ #ifndef SERVER_SIDE #define jack_destroy_shm(x) (0) #endif #endif /* __JackShmMem__android__ */ 1.9.12~dfsg/android/JackAndroidSemaphore.cpp0000644000000000000000000001762213214314510017511 0ustar rootroot/* Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackAndroidSemaphore.h" #include "JackTools.h" #include "JackConstants.h" #include "JackError.h" #include #include #include #include "IAndroidShm.h" #include "shm.h" #include "android/Shm.h" //android extension of shm.h namespace Jack { pthread_mutex_t JackAndroidSemaphore::mutex = PTHREAD_MUTEX_INITIALIZER; void JackAndroidSemaphore::BuildName(const char* client_name, const char* server_name, char* res, int size) { char ext_client_name[SYNC_MAX_NAME_SIZE + 1]; JackTools::RewriteName(client_name, ext_client_name); if (getenv("JACK_PROMISCUOUS_SERVER")) { snprintf(res, size, "jack_sem.%s_%s", server_name, ext_client_name); } else { snprintf(res, size, "jack_sem.%d_%s_%s", JackTools::GetUID(), server_name, ext_client_name); } } bool JackAndroidSemaphore::Signal() { int res; if (!fSemaphore) { jack_error("JackAndroidSemaphore::Signal name = %s already deallocated!!", fName); return false; } if (fFlush) return true; if ((res = sem_post(fSemaphore)) != 0) { jack_error("JackAndroidSemaphore::Signal name = %s err = %s", fName, strerror(errno)); } return (res == 0); } bool JackAndroidSemaphore::SignalAll() { int res; if (!fSemaphore) { jack_error("JackAndroidSemaphore::SignalAll name = %s already deallocated!!", fName); return false; } if (fFlush) return true; if ((res = sem_post(fSemaphore)) != 0) { jack_error("JackAndroidSemaphore::SignalAll name = %s err = %s", fName, strerror(errno)); } return (res == 0); } /* bool JackAndroidSemaphore::Wait() { int res; if (!fSemaphore) { jack_error("JackAndroidSemaphore::Wait name = %s already deallocated!!", fName); return false; } if ((res = sem_wait(fSemaphore)) != 0) { jack_error("JackAndroidSemaphore::Wait name = %s err = %s", fName, strerror(errno)); } return (res == 0); } */ bool JackAndroidSemaphore::Wait() { int res; while ((res = sem_wait(fSemaphore) < 0)) { jack_error("JackAndroidSemaphore::Wait name = %s err = %s", fName, strerror(errno)); if (errno != EINTR) { break; } } return (res == 0); } bool JackAndroidSemaphore::TimedWait(long usec) { int res; struct timeval now; timespec time; if (!fSemaphore) { jack_error("JackAndroidSemaphore::TimedWait name = %s already deallocated!!", fName); return false; } gettimeofday(&now, 0); time.tv_sec = now.tv_sec + usec / 1000000; long tv_usec = (now.tv_usec + (usec % 1000000)); time.tv_sec += tv_usec / 1000000; time.tv_nsec = (tv_usec % 1000000) * 1000; while ((res = sem_timedwait(fSemaphore, &time)) < 0) { jack_error("JackAndroidSemaphore::TimedWait err = %s", strerror(errno)); jack_log("JackAndroidSemaphore::TimedWait now : %ld %ld ", now.tv_sec, now.tv_usec); jack_log("JackAndroidSemaphore::TimedWait next : %ld %ld ", time.tv_sec, time.tv_nsec/1000); if (errno == ETIMEDOUT) { timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec = time.tv_sec - ts.tv_sec; ts.tv_nsec = time.tv_nsec - ts.tv_nsec; if (ts.tv_nsec < 0) { ts.tv_nsec += 1000000000; ts.tv_sec -= 1; } if (ts.tv_sec < 0 || ts.tv_nsec < 0) { jack_error("JackAndroidSemaphore::TimedWait time may changed or client killed already! wait again!"); gettimeofday(&now, 0); time.tv_sec = now.tv_sec + usec / 1000000; long tv_usec = (now.tv_usec + (usec % 1000000)); time.tv_sec += tv_usec / 1000000; time.tv_nsec = (tv_usec % 1000000) * 1000; if ((res = sem_timedwait(fSemaphore, &time)) < 0) { jack_error("JackAndroidSemaphore::TimedWait err = %s", strerror(errno)); jack_log("JackAndroidSemaphore::TimedWait now : %ld %ld ", now.tv_sec, now.tv_usec); jack_log("JackAndroidSemaphore::TimedWait next : %ld %ld ", time.tv_sec, time.tv_nsec/1000); } } } if (errno != EINTR) { break; } } return (res == 0); } // Server side : publish the semaphore in the global namespace bool JackAndroidSemaphore::Allocate(const char* name, const char* server_name, int value) { pthread_mutex_lock (&mutex); BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackAndroidSemaphore::Allocate name = %s val = %ld", fName, value); android::sp service = android::Shm::getShmService(); if(service == NULL){ jack_error("shm service is null"); return false; } fSemaphoreMemory = service->InitSemaphore(fName); if(fSemaphoreMemory != NULL){ fSemaphore = (sem_t*)(fSemaphoreMemory->getBase()); } if(fSemaphore == NULL) { jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno)); pthread_mutex_unlock (&mutex); return false; } else { sem_init(fSemaphore, 1, 0); jack_log("sem_init()"); pthread_mutex_unlock (&mutex); return true; } } // Client side : get the published semaphore from server bool JackAndroidSemaphore::ConnectInput(const char* name, const char* server_name) { pthread_mutex_lock (&mutex); BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackAndroidSemaphore::Connect name = %s", fName); // Temporary... if (fSemaphore) { jack_log("Already connected name = %s", name); pthread_mutex_unlock (&mutex); return true; } android::sp service = android::Shm::getShmService(); if(service == NULL){ jack_error("shm service is null"); return false; } fSemaphoreMemory = service->InitSemaphore(fName); if(fSemaphoreMemory != NULL){ fSemaphore = (sem_t*)(fSemaphoreMemory->getBase()); } if(fSemaphore == NULL) { jack_error("Connect: can't connect named semaphore name = %s err = %s", fName, strerror(errno)); pthread_mutex_unlock (&mutex); return false; } else { int val = 0; sem_getvalue(fSemaphore, &val); jack_log("JackAndroidSemaphore::Connect sem_getvalue %ld", val); pthread_mutex_unlock (&mutex); return true; } } bool JackAndroidSemaphore::Connect(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackAndroidSemaphore::ConnectOutput(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackAndroidSemaphore::Disconnect() { if (fSemaphore) { jack_log("JackAndroidSemaphore::Disconnect name = %s", fName); fSemaphore = NULL; } return true; } // Server side : destroy the semaphore void JackAndroidSemaphore::Destroy() { if (fSemaphore != NULL) { jack_log("JackAndroidSemaphore::Disconnect name = %s", fName); fSemaphore = NULL; } else { jack_error("JackAndroidSemaphore::Destroy semaphore == NULL"); } } } // end of namespace 1.9.12~dfsg/android/JackPlatformPlug_os.h0000644000000000000000000000534413214314510017045 0ustar rootroot/* Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPlatformPlug_android__ #define __JackPlatformPlug_android__ #define jack_server_dir "/data/misc/jack" #define jack_client_dir "/data/misc/jack" #define JACK_DEFAULT_DRIVER "alsa" namespace Jack { struct JackRequest; struct JackResult; class JackPosixMutex; class JackAndroidThread; class JackFifo; class JackSocketServerChannel; class JackSocketClientChannel; class JackSocketServerNotifyChannel; class JackSocketNotifyChannel; class JackClientSocket; class JackNetUnixSocket; } /* __JackPlatformMutex__ */ #include "JackPosixMutex.h" namespace Jack {typedef JackPosixMutex JackMutex; } /* __JackPlatformThread__ */ #include "JackAndroidThread.h" namespace Jack { typedef JackAndroidThread JackThread; } /* __JackPlatformSynchro__ client activation */ /* #include "JackFifo.h" namespace Jack { typedef JackFifo JackSynchro; } */ #include "JackAndroidSemaphore.h" namespace Jack { typedef JackAndroidSemaphore JackSynchro; } /* __JackPlatformChannelTransaction__ */ /* #include "JackSocket.h" namespace Jack { typedef JackClientSocket JackChannelTransaction; } */ /* __JackPlatformProcessSync__ */ #include "JackPosixProcessSync.h" namespace Jack { typedef JackPosixProcessSync JackProcessSync; } /* __JackPlatformServerChannel__ */ #include "JackSocketServerChannel.h" namespace Jack { typedef JackSocketServerChannel JackServerChannel; } /* __JackPlatformClientChannel__ */ #include "JackSocketClientChannel.h" namespace Jack { typedef JackSocketClientChannel JackClientChannel; } /* __JackPlatformServerNotifyChannel__ */ #include "JackSocketServerNotifyChannel.h" namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; } /* __JackPlatformNotifyChannel__ */ #include "JackSocketNotifyChannel.h" namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; } /* __JackPlatformNetSocket__ */ #include "JackNetUnixSocket.h" namespace Jack { typedef JackNetUnixSocket JackNetSocket; } #endif 1.9.12~dfsg/android/Shm.h0000644000000000000000000001301713214314510013662 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2005-2012 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_shm_android_h__ #define __jack_shm_android_h__ #include #include #include "types.h" #include "JackCompilerDeps.h" #include #include #ifdef __cplusplus extern "C" { #endif #define JACK_SHM_REGISTRY_FD -1 #define JACK_SHM_HEAP_ENOUGH_COUNT 300 void jack_instantiate(); #ifdef __cplusplus } #endif namespace android { class IAndroidShm; class Shm { public: static Shm* Instantiate(); virtual ~Shm(); private: Shm(); Shm( const Shm&); Shm& operator=(const Shm); private: void set_server_prefix (const char *server_name); int server_initialize_shm (int new_registry); int shm_lock_registry (void); void shm_unlock_registry (void); int access_registry (jack_shm_info_t *ri); void remove_shm (jack_shm_id_t *id); int create_registry (jack_shm_info_t *ri); int shm_validate_registry (); int GetUID(); int GetPID(); void shm_init_registry (); void release_shm_entry (jack_shm_registry_index_t index); jack_shm_registry_t * get_free_shm_info (); public: static void jack_shm_copy_from_registry (jack_shm_info_t*, jack_shm_registry_index_t); static void jack_shm_copy_to_registry (jack_shm_info_t*, jack_shm_registry_index_t*); static int jack_release_shm_info (jack_shm_registry_index_t); static char* jack_shm_addr (jack_shm_info_t* si); static int jack_register_server (const char *server_name, int new_registry); static int jack_unregister_server (const char *server_name); static int jack_initialize_shm (const char *server_name); static int jack_initialize_shm_server (void); static int jack_initialize_shm_client (void); static int jack_cleanup_shm (void); static int jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result); static void jack_release_shm (jack_shm_info_t*); static void jack_release_lib_shm (jack_shm_info_t*); static void jack_destroy_shm (jack_shm_info_t*); static int jack_attach_shm (jack_shm_info_t*); static int jack_attach_lib_shm (jack_shm_info_t*); static int jack_attach_shm_read (jack_shm_info_t*); static int jack_attach_lib_shm_read (jack_shm_info_t*); static int jack_resize_shm (jack_shm_info_t*, jack_shmsize_t size); public: void shm_copy_from_registry (jack_shm_info_t*, jack_shm_registry_index_t); void shm_copy_to_registry (jack_shm_info_t*, jack_shm_registry_index_t*); int release_shm_info (jack_shm_registry_index_t); char* shm_addr (unsigned int fd); // here begin the API int register_server (const char *server_name, int new_registry); int unregister_server (const char *server_name); int initialize_shm (const char *server_name); int initialize_shm_server (void); int initialize_shm_client (void); int cleanup_shm (void); int shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result); void release_shm (jack_shm_info_t*); void release_lib_shm (jack_shm_info_t*); void destroy_shm (jack_shm_info_t*); int attach_shm (jack_shm_info_t*); int attach_lib_shm (jack_shm_info_t*); int attach_shm_read (jack_shm_info_t*); int attach_lib_shm_read (jack_shm_info_t*); int resize_shm (jack_shm_info_t*, jack_shmsize_t size); private: static jack_shmtype_t jack_shmtype; static jack_shm_id_t registry_id; static jack_shm_fd_t registry_fd; static jack_shm_info_t registry_info; static jack_shm_header_t *jack_shm_header; static jack_shm_registry_t *jack_shm_registry; static char jack_shm_server_prefix[JACK_SERVER_NAME_SIZE+1]; static int semid; static pthread_mutex_t mutex; static Shm* ref; void jack_release_shm_entry (jack_shm_registry_index_t index); int jack_shm_lock_registry (void); void jack_shm_unlock_registry (void); //static sp mShmService; static sp mShmMemBase[JACK_SHM_HEAP_ENOUGH_COUNT]; public: static sp getShmService(); }; }; #endif /* __jack_shm_android_h__ */ 1.9.12~dfsg/android/JackSystemDeps_os.h0000644000000000000000000000200313214314510016516 0ustar rootroot/* Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSystemDeps_android__ #define __JackSystemDeps_android__ #include "../posix/JackSystemDeps_os.h" /** * bionic c dependant functions */ #define pthread_setcanceltype(x,y) (0) #endif /* __JackSystemDeps_android__ */ 1.9.12~dfsg/android/Android.mk0000644000000000000000000014760613214314510014707 0ustar rootroot# # jack-1.9.10 # LOCAL_PATH := $(call my-dir) JACK_ROOT := $(call my-dir)/.. SUPPORT_ALSA_IN_JACK := true SUPPORT_ANDROID_REALTIME_SCHED := false ifeq ($(TARGET_BOARD_PLATFORM),mrvl) ALSA_INCLUDES := vendor/marvell/external/alsa-lib/include else ALSA_INCLUDES := vendor/samsung/common/external/alsa-lib/include endif JACK_STL_LDFLAGS := -Lprebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI) -lgnustl_static JACK_STL_INCLUDES := $(JACK_ROOT)/android/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI)/include \ prebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI)/include \ prebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/include ########################################################## # common ########################################################## common_cflags := -O0 -g -Wall -fexceptions -fvisibility=hidden -DHAVE_CONFIG_H common_cflags += -Wno-unused -Wno-sign-compare -Wno-deprecated-declarations -Wno-cpp common_cppflags := -frtti -Wno-sign-promo -fcheck-new common_shm_cflags := -O0 -g -Wall -fexceptions -DHAVE_CONFIG_H -Wno-unused ifeq ($(TARGET_BOARD_PLATFORM),clovertrail) common_ldflags := -ldl else common_ldflags := endif common_c_includes := \ $(JACK_ROOT) \ $(JACK_ROOT)/common \ $(JACK_ROOT)/common/jack \ $(JACK_ROOT)/android \ $(JACK_ROOT)/linux \ $(JACK_ROOT)/linux/alsa \ $(JACK_ROOT)/posix \ $(JACK_STL_INCLUDES) # copy common source file common_libsource_server_dir = .server common_libsource_client_dir = .client $(shell rm -rf $(LOCAL_PATH)/$(common_libsource_server_dir)) $(shell rm -rf $(LOCAL_PATH)/$(common_libsource_client_dir)) $(shell mkdir $(LOCAL_PATH)/$(common_libsource_server_dir)) $(shell mkdir $(LOCAL_PATH)/$(common_libsource_client_dir)) $(shell cp -f $(LOCAL_PATH)/../common/JackActivationCount.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackActivationCount.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackAPI.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackAPI.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackClient.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackClient.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackConnectionManager.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackConnectionManager.cpp) $(shell cp -f $(LOCAL_PATH)/../common/ringbuffer.c $(LOCAL_PATH)/$(common_libsource_server_dir)/ringbuffer.c) $(shell cp -f $(LOCAL_PATH)/JackError.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackError.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackException.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackException.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackFrameTimer.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackFrameTimer.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackGraphManager.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackGraphManager.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackPort.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackPort.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackPortType.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackPortType.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackAudioPort.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackAudioPort.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackMidiPort.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackMidiPort.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackMidiAPI.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackMidiAPI.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackEngineControl.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackEngineControl.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackShmMem.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackShmMem.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackGenericClientChannel.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackGenericClientChannel.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackGlobals.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackGlobals.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackDebugClient.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackDebugClient.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackTransportEngine.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackTransportEngine.cpp) $(shell cp -f $(LOCAL_PATH)/../common/timestamps.c $(LOCAL_PATH)/$(common_libsource_server_dir)/timestamps.c) $(shell cp -f $(LOCAL_PATH)/../common/JackTools.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackTools.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackMessageBuffer.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackMessageBuffer.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackEngineProfiling.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackEngineProfiling.cpp) $(shell cp -f $(LOCAL_PATH)/JackAndroidThread.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackAndroidThread.cpp) $(shell cp -f $(LOCAL_PATH)/JackAndroidSemaphore.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackAndroidSemaphore.cpp) $(shell cp -f $(LOCAL_PATH)/../posix/JackPosixProcessSync.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackPosixProcessSync.cpp) $(shell cp -f $(LOCAL_PATH)/../posix/JackPosixMutex.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackPosixMutex.cpp) $(shell cp -f $(LOCAL_PATH)/../posix/JackSocket.cpp $(LOCAL_PATH)/$(common_libsource_server_dir)/JackSocket.cpp) $(shell cp -f $(LOCAL_PATH)/../linux/JackLinuxTime.c $(LOCAL_PATH)/$(common_libsource_server_dir)/JackLinuxTime.c) $(shell cp -f $(LOCAL_PATH)/../common/JackActivationCount.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackActivationCount.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackAPI.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackAPI.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackClient.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackClient.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackConnectionManager.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackConnectionManager.cpp) $(shell cp -f $(LOCAL_PATH)/../common/ringbuffer.c $(LOCAL_PATH)/$(common_libsource_client_dir)/ringbuffer.c) $(shell cp -f $(LOCAL_PATH)/JackError.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackError.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackException.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackException.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackFrameTimer.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackFrameTimer.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackGraphManager.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackGraphManager.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackPort.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackPort.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackPortType.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackPortType.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackAudioPort.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackAudioPort.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackMidiPort.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackMidiPort.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackMidiAPI.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackMidiAPI.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackEngineControl.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackEngineControl.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackShmMem.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackShmMem.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackGenericClientChannel.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackGenericClientChannel.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackGlobals.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackGlobals.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackDebugClient.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackDebugClient.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackTransportEngine.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackTransportEngine.cpp) $(shell cp -f $(LOCAL_PATH)/../common/timestamps.c $(LOCAL_PATH)/$(common_libsource_client_dir)/timestamps.c) $(shell cp -f $(LOCAL_PATH)/../common/JackTools.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackTools.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackMessageBuffer.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackMessageBuffer.cpp) $(shell cp -f $(LOCAL_PATH)/../common/JackEngineProfiling.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackEngineProfiling.cpp) $(shell cp -f $(LOCAL_PATH)/JackAndroidThread.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackAndroidThread.cpp) $(shell cp -f $(LOCAL_PATH)/JackAndroidSemaphore.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackAndroidSemaphore.cpp) $(shell cp -f $(LOCAL_PATH)/../posix/JackPosixProcessSync.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackPosixProcessSync.cpp) $(shell cp -f $(LOCAL_PATH)/../posix/JackPosixMutex.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackPosixMutex.cpp) $(shell cp -f $(LOCAL_PATH)/../posix/JackSocket.cpp $(LOCAL_PATH)/$(common_libsource_client_dir)/JackSocket.cpp) $(shell cp -f $(LOCAL_PATH)/../linux/JackLinuxTime.c $(LOCAL_PATH)/$(common_libsource_client_dir)/JackLinuxTime.c) common_libsource_server := \ $(common_libsource_server_dir)/JackActivationCount.cpp \ $(common_libsource_server_dir)/JackAPI.cpp \ $(common_libsource_server_dir)/JackClient.cpp \ $(common_libsource_server_dir)/JackConnectionManager.cpp \ $(common_libsource_server_dir)/ringbuffer.c \ $(common_libsource_server_dir)/JackError.cpp \ $(common_libsource_server_dir)/JackException.cpp \ $(common_libsource_server_dir)/JackFrameTimer.cpp \ $(common_libsource_server_dir)/JackGraphManager.cpp \ $(common_libsource_server_dir)/JackPort.cpp \ $(common_libsource_server_dir)/JackPortType.cpp \ $(common_libsource_server_dir)/JackAudioPort.cpp \ $(common_libsource_server_dir)/JackMidiPort.cpp \ $(common_libsource_server_dir)/JackMidiAPI.cpp \ $(common_libsource_server_dir)/JackEngineControl.cpp \ $(common_libsource_server_dir)/JackShmMem.cpp \ $(common_libsource_server_dir)/JackGenericClientChannel.cpp \ $(common_libsource_server_dir)/JackGlobals.cpp \ $(common_libsource_server_dir)/JackDebugClient.cpp \ $(common_libsource_server_dir)/JackTransportEngine.cpp \ $(common_libsource_server_dir)/timestamps.c \ $(common_libsource_server_dir)/JackTools.cpp \ $(common_libsource_server_dir)/JackMessageBuffer.cpp \ $(common_libsource_server_dir)/JackEngineProfiling.cpp \ $(common_libsource_server_dir)/JackAndroidThread.cpp \ $(common_libsource_server_dir)/JackAndroidSemaphore.cpp \ $(common_libsource_server_dir)/JackPosixProcessSync.cpp \ $(common_libsource_server_dir)/JackPosixMutex.cpp \ $(common_libsource_server_dir)/JackSocket.cpp \ $(common_libsource_server_dir)/JackLinuxTime.c common_libsource_client := \ $(common_libsource_client_dir)/JackActivationCount.cpp \ $(common_libsource_client_dir)/JackAPI.cpp \ $(common_libsource_client_dir)/JackClient.cpp \ $(common_libsource_client_dir)/JackConnectionManager.cpp \ $(common_libsource_client_dir)/ringbuffer.c \ $(common_libsource_client_dir)/JackError.cpp \ $(common_libsource_client_dir)/JackException.cpp \ $(common_libsource_client_dir)/JackFrameTimer.cpp \ $(common_libsource_client_dir)/JackGraphManager.cpp \ $(common_libsource_client_dir)/JackPort.cpp \ $(common_libsource_client_dir)/JackPortType.cpp \ $(common_libsource_client_dir)/JackAudioPort.cpp \ $(common_libsource_client_dir)/JackMidiPort.cpp \ $(common_libsource_client_dir)/JackMidiAPI.cpp \ $(common_libsource_client_dir)/JackEngineControl.cpp \ $(common_libsource_client_dir)/JackShmMem.cpp \ $(common_libsource_client_dir)/JackGenericClientChannel.cpp \ $(common_libsource_client_dir)/JackGlobals.cpp \ $(common_libsource_client_dir)/JackDebugClient.cpp \ $(common_libsource_client_dir)/JackTransportEngine.cpp \ $(common_libsource_client_dir)/timestamps.c \ $(common_libsource_client_dir)/JackTools.cpp \ $(common_libsource_client_dir)/JackMessageBuffer.cpp \ $(common_libsource_client_dir)/JackEngineProfiling.cpp \ $(common_libsource_client_dir)/JackAndroidThread.cpp \ $(common_libsource_client_dir)/JackAndroidSemaphore.cpp \ $(common_libsource_client_dir)/JackPosixProcessSync.cpp \ $(common_libsource_client_dir)/JackPosixMutex.cpp \ $(common_libsource_client_dir)/JackSocket.cpp \ $(common_libsource_client_dir)/JackLinuxTime.c server_libsource := \ ../common/JackAudioDriver.cpp \ ../common/JackTimedDriver.cpp \ ../common/JackMidiDriver.cpp \ ../common/JackDriver.cpp \ ../common/JackEngine.cpp \ ../common/JackExternalClient.cpp \ ../common/JackFreewheelDriver.cpp \ ../common/JackInternalClient.cpp \ ../common/JackServer.cpp \ ../common/JackThreadedDriver.cpp \ ../common/JackRestartThreadedDriver.cpp \ ../common/JackWaitThreadedDriver.cpp \ ../common/JackServerAPI.cpp \ ../common/JackDriverLoader.cpp \ ../common/JackServerGlobals.cpp \ ../common/JackControlAPI.cpp \ JackControlAPIAndroid.cpp \ ../common/JackNetTool.cpp \ ../common/JackNetInterface.cpp \ ../common/JackArgParser.cpp \ ../common/JackRequestDecoder.cpp \ ../common/JackMidiAsyncQueue.cpp \ ../common/JackMidiAsyncWaitQueue.cpp \ ../common/JackMidiBufferReadQueue.cpp \ ../common/JackMidiBufferWriteQueue.cpp \ ../common/JackMidiRawInputWriteQueue.cpp \ ../common/JackMidiRawOutputWriteQueue.cpp \ ../common/JackMidiReadQueue.cpp \ ../common/JackMidiReceiveQueue.cpp \ ../common/JackMidiSendQueue.cpp \ ../common/JackMidiUtil.cpp \ ../common/JackMidiWriteQueue.cpp \ ../posix/JackSocketServerChannel.cpp \ ../posix/JackSocketNotifyChannel.cpp \ ../posix/JackSocketServerNotifyChannel.cpp \ ../posix/JackNetUnixSocket.cpp net_libsource := \ ../common/JackNetAPI.cpp \ ../common/JackNetInterface.cpp \ ../common/JackNetTool.cpp \ ../common/JackException.cpp \ ../common/JackAudioAdapterInterface.cpp \ ../common/JackLibSampleRateResampler.cpp \ ../common/JackResampler.cpp \ ../common/JackGlobals.cpp \ ../posix/JackPosixMutex.cpp \ ../common/ringbuffer.c \ ../posix/JackNetUnixSocket.cpp \ $(common_libsource_server_dir)/JackAndroidThread.cpp \ ../linux/JackLinuxTime.c client_libsource := \ ../common/JackLibClient.cpp \ ../common/JackLibAPI.cpp \ ../posix/JackSocketClientChannel.cpp \ ../posix/JackPosixServerLaunch.cpp netadapter_libsource := \ ../common/JackResampler.cpp \ ../common/JackLibSampleRateResampler.cpp \ ../common/JackAudioAdapter.cpp \ ../common/JackAudioAdapterInterface.cpp \ ../common/JackNetAdapter.cpp audioadapter_libsource := \ ../common/JackResampler.cpp \ ../common/JackLibSampleRateResampler.cpp \ ../common/JackAudioAdapter.cpp \ ../common/JackAudioAdapterInterface.cpp \ ../common/JackAudioAdapterFactory.cpp \ ../linux/alsa/JackAlsaAdapter.cpp ifeq ($(SUPPORT_ANDROID_REALTIME_SCHED), true) sched_c_include := bionic/libc/bionic \ frameworks/av/services/audioflinger endif # ======================================================== # libjackserver.so # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := $(common_libsource_server) $(server_libsource) LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libjackshm LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := libjackserver ifeq ($(SUPPORT_ANDROID_REALTIME_SCHED), true) LOCAL_CFLAGS += -DJACK_ANDROID_REALTIME_SCHED LOCAL_C_INCLUDES += $(sched_c_include) LOCAL_SHARED_LIBRARIES += libbinder LOCAL_STATIC_LIBRARIES := libscheduling_policy endif include $(BUILD_SHARED_LIBRARY) ## ======================================================== ## libjacknet.so ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := $(net_libsource) #LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE #LOCAL_CPPFLAGS := $(common_cppflags) #LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) #LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include #LOCAL_SHARED_LIBRARIES := libc libdl libcutils libsamplerate #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := libjacknet # #include $(BUILD_SHARED_LIBRARY) # ======================================================== # libjack.so # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := $(common_libsource_client) $(client_libsource) LOCAL_CFLAGS := $(common_cflags) LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libjackshm LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := libjack ifeq ($(SUPPORT_ANDROID_REALTIME_SCHED), true) LOCAL_CFLAGS += -DJACK_ANDROID_REALTIME_SCHED LOCAL_C_INCLUDES += $(sched_c_include) LOCAL_SHARED_LIBRARIES += libbinder LOCAL_STATIC_LIBRARIES := libscheduling_policy endif include $(BUILD_SHARED_LIBRARY) # ======================================================== # netmanager.so # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../common/JackNetManager.cpp LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := netmanager include $(BUILD_SHARED_LIBRARY) # ======================================================== # profiler.so # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../common/JackProfiler.cpp LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := profiler include $(BUILD_SHARED_LIBRARY) ## ======================================================== ## netadapter.so ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := $(netadapter_libsource) #LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE #LOCAL_CPPFLAGS := $(common_cppflags) #LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) #LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include #LOCAL_SHARED_LIBRARIES := libc libdl libcutils libsamplerate libjackserver #LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := netadapter # #include $(BUILD_SHARED_LIBRARY) ## ======================================================== ## audioadapter.so ## ======================================================== #ifeq ($(SUPPORT_ALSA_IN_JACK),true) #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := $(audioadapter_libsource) #LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE -D_POSIX_SOURCE #LOCAL_CPPFLAGS := $(common_cppflags) #LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) #LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include $(ALSA_INCLUDES) #LOCAL_SHARED_LIBRARIES := libc libdl libcutils libasound libsamplerate libjackserver #LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := audioadapter # #include $(BUILD_SHARED_LIBRARY) ##endif # ======================================================== # in.so - sapaproxy internal client # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := JackSapaProxy.cpp JackSapaProxyIn.cpp LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := in include $(BUILD_SHARED_LIBRARY) # ======================================================== # out.so - sapaproxy internal client # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := JackSapaProxy.cpp JackSapaProxyOut.cpp LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := out include $(BUILD_SHARED_LIBRARY) ########################################################## # linux ########################################################## # ======================================================== # jackd # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := \ ../common/Jackdmp.cpp # ../dbus/reserve.c # ../dbus/audio_reserve.c LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(JACK_STL_LDFLAGS) -ldl -Wl,--no-fatal-warnings LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libutils libjackserver LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jackd include $(BUILD_EXECUTABLE) # ======================================================== # driver - dummy # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../common/JackDummyDriver.cpp #'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_dummy include $(BUILD_SHARED_LIBRARY) # ======================================================== # driver - alsa # ======================================================== ifeq ($(SUPPORT_ALSA_IN_JACK),true) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ ../linux/alsa/JackAlsaDriver.cpp \ ../linux/alsa/alsa_midi_jackmp.cpp \ ../common/memops.c \ ../linux/alsa/generic_hw.c \ ../linux/alsa/hdsp.c \ ../linux/alsa/alsa_driver.c \ ../linux/alsa/hammerfall.c \ ../linux/alsa/ice1712.c # ../linux/alsa/alsa_rawmidi.c # ../linux/alsa/alsa_seqmidi.c #'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) $(ALSA_INCLUDES) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver libasound LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_alsa include $(BUILD_SHARED_LIBRARY) endif ## ======================================================== ## driver - alsarawmidi ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := \ # ../linux/alsarawmidi/JackALSARawMidiDriver.cpp \ # ../linux/alsarawmidi/JackALSARawMidiInputPort.cpp \ # ../linux/alsarawmidi/JackALSARawMidiOutputPort.cpp \ # ../linux/alsarawmidi/JackALSARawMidiPort.cpp \ # ../linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp \ # ../linux/alsarawmidi/JackALSARawMidiSendQueue.cpp \ # ../linux/alsarawmidi/JackALSARawMidiUtil.cpp ##'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD #LOCAL_CFLAGS := $(common_cflags) -D_POSIX_SOURCE -D__ALSA_RAWMIDI_H #LOCAL_CPPFLAGS := $(common_cppflags) #LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) #LOCAL_C_INCLUDES := $(common_c_includes) $(ALSA_INCLUDES) #LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver libasound #LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := jack_alsarawmidi # #include $(BUILD_SHARED_LIBRARY) ## LIBFREEBOB required ## ======================================================== ## driver - freebob ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := ../linux/freebob/JackFreebobDriver.cpp ##'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD #LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE #LOCAL_CPPFLAGS := $(common_cppflags) #LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) #LOCAL_C_INCLUDES := $(common_c_includes) #LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver #LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := jack_freebob # #include $(BUILD_SHARED_LIBRARY) ## LIBFFADO required ## ======================================================== ## driver - firewire ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := \ # ../linux/firewire/JackFFADODriver.cpp \ # ../linux/firewire/JackFFADOMidiInputPort.cpp \ # ../linux/firewire/JackFFADOMidiOutputPort.cpp \ # ../linux/firewire/JackFFADOMidiReceiveQueue.cpp \ # ../linux/firewire/JackFFADOMidiSendQueue.cpp ##'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD #LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE #LOCAL_CPPFLAGS := $(common_cppflags) #LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) #LOCAL_C_INCLUDES := $(common_c_includes) #LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver #LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := jack_firewire # #include $(BUILD_SHARED_LIBRARY) # ======================================================== # driver - net # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../common/JackNetDriver.cpp #'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_net include $(BUILD_SHARED_LIBRARY) # ======================================================== # driver - loopback # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../common/JackLoopbackDriver.cpp #'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_loopback include $(BUILD_SHARED_LIBRARY) ##HAVE_SAMPLERATE, HAVE_CELT required ## ======================================================== ## driver - netone ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := \ # ../common/JackNetOneDriver.cpp \ # ../common/netjack.c \ # ../common/netjack_packet.c ##'HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD #LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE #LOCAL_CPPFLAGS := $(common_cppflags) #LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) #LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include #LOCAL_SHARED_LIBRARIES := libc libdl libcutils libsamplerate libjackserver #LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := jack_netone # #include $(BUILD_SHARED_LIBRARY) ########################################################## # android ########################################################## # ======================================================== # libjackshm.so # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := BnAndroidShm.cpp BpAndroidShm.cpp IAndroidShm.cpp AndroidShm.cpp Shm.cpp LOCAL_CFLAGS := $(common_shm_cflags) -DSERVER_SIDE LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libbinder LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := libjackshm include $(BUILD_SHARED_LIBRARY) # ======================================================== # jack_goldfish.so - Goldfish driver for emulator # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := JackGoldfishDriver.cpp LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_goldfish include $(BUILD_SHARED_LIBRARY) # ======================================================== # jack_opensles.so - OpenSL ES driver # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := JackOpenSLESDriver.cpp opensl_io.c LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) frameworks/wilhelm/include LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver libOpenSLES LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_opensles include $(BUILD_SHARED_LIBRARY) ########################################################## # android/AndroidShmServer ########################################################## # ======================================================== # androidshmservice # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ./AndroidShmServer/main_androidshmservice.cpp LOCAL_CFLAGS := $(common_cflags) LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libcutils libutils libbinder libjackshm LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE:= androidshmservice include $(BUILD_EXECUTABLE) # ======================================================== # shmservicetest # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ./AndroidShmServer/test/shmservicetest.cpp LOCAL_CFLAGS := $(common_cflags) -DLOG_TAG=\"ShmServiceTest\" LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libcutils libutils libjackshm libbinder LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := shmservicetest include $(BUILD_EXECUTABLE) # ======================================================== # shmservicedump # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ./AndroidShmServer/test/shmservicedump.cpp LOCAL_CFLAGS := $(common_cflags) -DLOG_TAG=\"ShmServiceDump\" LOCAL_CPPFLAGS := $(common_cppflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_SHARED_LIBRARIES := libcutils libutils libjackshm libbinder LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := shmservicedump include $(BUILD_EXECUTABLE) ########################################################## # example-clients ########################################################## # ======================================================== # jack_freewheel # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/freewheel.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_freewheel include $(BUILD_EXECUTABLE) # ======================================================== # jack_connect # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/connect.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_connect include $(BUILD_EXECUTABLE) # ======================================================== # jack_disconnect # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/connect.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_disconnect include $(BUILD_EXECUTABLE) # ======================================================== # jack_lsp # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/lsp.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_lsp include $(BUILD_EXECUTABLE) # ======================================================== # jack_metro # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/metro.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_metro include $(BUILD_EXECUTABLE) # ======================================================== # jack_midiseq # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/midiseq.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_midiseq include $(BUILD_EXECUTABLE) # ======================================================== # jack_midisine # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/midisine.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_midisine include $(BUILD_EXECUTABLE) # ======================================================== # jack_showtime # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/showtime.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_showtime include $(BUILD_EXECUTABLE) # ======================================================== # jack_simple_client # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/simple_client.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_simple_client include $(BUILD_EXECUTABLE) # ======================================================== # jack_zombie # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/zombie.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_zombie include $(BUILD_EXECUTABLE) # ======================================================== # jack_load # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/ipload.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_load include $(BUILD_EXECUTABLE) # ======================================================== # jack_unload # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/ipunload.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_unload include $(BUILD_EXECUTABLE) # ======================================================== # jack_alias # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/alias.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_alias include $(BUILD_EXECUTABLE) # ======================================================== # jack_bufsize # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/bufsize.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_bufsize include $(BUILD_EXECUTABLE) # ======================================================== # jack_wait # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/wait.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_wait include $(BUILD_EXECUTABLE) # ======================================================== # jack_samplerate # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/samplerate.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_samplerate include $(BUILD_EXECUTABLE) # ======================================================== # jack_evmon # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/evmon.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_evmon include $(BUILD_EXECUTABLE) # ======================================================== # jack_monitor_client # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/monitor_client.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_monitor_client include $(BUILD_EXECUTABLE) # ======================================================== # jack_thru # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/thru_client.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_thru include $(BUILD_EXECUTABLE) # ======================================================== # jack_cpu_load # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/cpu_load.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_cpu_load include $(BUILD_EXECUTABLE) # ======================================================== # jack_simple_session_client # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/simple_session_client.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_simple_session_client include $(BUILD_EXECUTABLE) # ======================================================== # jack_session_notify # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/session_notify.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_session_notify include $(BUILD_EXECUTABLE) # ======================================================== # jack_server_control # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/server_control.cpp LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_server_control include $(BUILD_EXECUTABLE) ## ======================================================== ## jack_net_slave ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := ../example-clients/netslave.c #LOCAL_CFLAGS := $(common_cflags) #LOCAL_LDFLAGS := $(common_ldflags) #LOCAL_C_INCLUDES := $(common_c_includes) #LOCAL_SHARED_LIBRARIES := libjacknet #LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := jack_net_slave # #include $(BUILD_EXECUTABLE) ## ======================================================== ## jack_net_master ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := ../example-clients/netmaster.c #LOCAL_CFLAGS := $(common_cflags) #LOCAL_LDFLAGS := $(common_ldflags) #LOCAL_C_INCLUDES := $(common_c_includes) #LOCAL_SHARED_LIBRARIES := libjacknet #LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := jack_net_master # #include $(BUILD_EXECUTABLE) # ======================================================== # jack_latent_client # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/latent_client.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_latent_client include $(BUILD_EXECUTABLE) # ======================================================== # jack_midi_dump # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/midi_dump.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_midi_dump include $(BUILD_EXECUTABLE) # ======================================================== # jack_midi_latency_test # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/midi_latency_test.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_midi_latency_test include $(BUILD_EXECUTABLE) # ======================================================== # jack_transport # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/transport.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_transport include $(BUILD_EXECUTABLE) ## ======================================================== ## jack_rec ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := ../example-clients/capture_client.c #LOCAL_CFLAGS := $(common_cflags) #LOCAL_LDFLAGS := $(common_ldflags) #LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsndfile/src #LOCAL_SHARED_LIBRARIES := libjack libsndfile #LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := jack_rec # #include $(BUILD_EXECUTABLE) ## ======================================================== ## jack_netsource ## ======================================================== #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := ../example-clients/netsource.c ../common/netjack_packet.c #LOCAL_CFLAGS := $(common_cflags) -DNO_JACK_ERROR #LOCAL_LDFLAGS := $(common_ldflags) #LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include #LOCAL_SHARED_LIBRARIES := libsamplerate libjack #LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := jack_netsource # #include $(BUILD_EXECUTABLE) ## ======================================================== ## alsa_in ## ======================================================== #ifeq ($(SUPPORT_ALSA_IN_JACK),true) #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := ../example-clients/alsa_in.c ../common/memops.c #LOCAL_CFLAGS := $(common_cflags) -DNO_JACK_ERROR -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 #LOCAL_LDFLAGS := $(common_ldflags) #LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include $(ALSA_INCLUDES) #LOCAL_SHARED_LIBRARIES := libasound libsamplerate libjack #LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := alsa_in # #include $(BUILD_EXECUTABLE) #endif ## ======================================================== ## alsa_out ## ======================================================== #ifeq ($(SUPPORT_ALSA_IN_JACK),true) #include $(CLEAR_VARS) # #LOCAL_SRC_FILES := ../example-clients/alsa_out.c ../common/memops.c #LOCAL_CFLAGS := $(common_cflags) -DNO_JACK_ERROR -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 #LOCAL_LDFLAGS := $(common_ldflags) #LOCAL_C_INCLUDES := $(common_c_includes) $(JACK_ROOT)/../libsamplerate/include $(ALSA_INCLUDES) #LOCAL_SHARED_LIBRARIES := libasound libsamplerate libjack #LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) #LOCAL_MODULE_TAGS := eng optional #LOCAL_MODULE := alsa_out # #include $(BUILD_EXECUTABLE) #endif # ======================================================== # inprocess # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../example-clients/inprocess.c LOCAL_CFLAGS := $(common_cflags) -DSERVER_SIDE LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libc libdl libcutils libjackserver LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/jack LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := inprocess include $(BUILD_SHARED_LIBRARY) ########################################################## # tests ########################################################## # ======================================================== # jack_test # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../tests/test.cpp LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack libjackshm LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_test include $(BUILD_EXECUTABLE) # ======================================================== # jack_cpu # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../tests/cpu.c LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack libjackshm LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_cpu include $(BUILD_EXECUTABLE) # ======================================================== # jack_iodelay # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../tests/iodelay.cpp LOCAL_CFLAGS := $(common_cflags) LOCAL_CFLAGS += -Wno-narrowing LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack libjackshm LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_iodelay include $(BUILD_EXECUTABLE) # ======================================================== # jack_multiple_metro # ======================================================== include $(CLEAR_VARS) LOCAL_SRC_FILES := ../tests/external_metro.cpp LOCAL_CFLAGS := $(common_cflags) LOCAL_LDFLAGS := $(common_ldflags) $(JACK_STL_LDFLAGS) LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := libjack libjackshm LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng optional LOCAL_MODULE := jack_multiple_metro include $(BUILD_EXECUTABLE) 1.9.12~dfsg/android/JackAndroidThread.cpp0000644000000000000000000002304213214314510016766 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackAndroidThread.h" #include "JackError.h" #include "JackTime.h" #include "JackGlobals.h" #include // for memset #include // for _POSIX_PRIORITY_SCHEDULING check #include #ifdef JACK_ANDROID_REALTIME_SCHED #include "SchedulingPolicyService.h" #endif //#define JACK_SCHED_POLICY SCHED_RR #define JACK_SCHED_POLICY SCHED_FIFO namespace Jack { void JackAndroidThread::thread_exit_handler(int sig) { printf("this signal is %d \n", sig); pthread_exit(0); } void* JackAndroidThread::ThreadHandler(void* arg) { JackAndroidThread* obj = (JackAndroidThread*)arg; JackRunnableInterface* runnable = obj->fRunnable; int err; // Signal creation thread when started with StartSync jack_log("JackAndroidThread::ThreadHandler : start"); obj->fStatus = kIniting; // Call Init method if (!runnable->Init()) { jack_error("Thread init fails: thread quits"); return 0; } obj->fStatus = kRunning; // If Init succeed, start the thread loop bool res = true; while (obj->fStatus == kRunning && res) { res = runnable->Execute(); } jack_log("JackAndroidThread::ThreadHandler : exit"); pthread_exit(0); return 0; // never reached } int JackAndroidThread::Start() { fStatus = kStarting; // Check if the thread was correctly started if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; } else { return 0; } } int JackAndroidThread::StartSync() { fStatus = kStarting; if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; } else { int count = 0; while (fStatus == kStarting && ++count < 1000) { JackSleep(1000); } return (count == 1000) ? -1 : 0; } } int JackAndroidThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) { pthread_attr_t attributes; struct sched_param rt_param; pthread_attr_init(&attributes); int res; struct sigaction actions; memset(&actions, 0, sizeof(actions)); sigemptyset(&actions.sa_mask); actions.sa_flags = 0; actions.sa_handler = thread_exit_handler; sigaction(SIGUSR1,&actions,NULL); if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) { jack_error("Cannot request joinable thread creation for thread res = %d", res); return -1; } if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) { jack_error("Cannot set scheduling scope for thread res = %d", res); return -1; } if (realtime) { jack_log("JackAndroidThread::StartImp : create RT thread"); if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) { jack_error("Cannot set RR scheduling class for RT thread res = %d", res); return -1; } memset(&rt_param, 0, sizeof(rt_param)); rt_param.sched_priority = priority; if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { jack_error("Cannot set scheduling priority for RT thread res = %d", res); return -1; } } else { jack_log("JackAndroidThread::StartImp : create non RT thread"); } if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) { jack_error("Cannot set thread stack size res = %d", res); return -1; } if ((res = JackGlobals::fJackThreadCreator(thread, &attributes, start_routine, arg))) { jack_error("Cannot create thread res = %d", res); return -1; } pthread_attr_destroy(&attributes); return 0; } int JackAndroidThread::Kill() { if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackAndroidThread::Kill"); void* status; pthread_kill(fThread, SIGUSR1); pthread_join(fThread, &status); fStatus = kIdle; fThread = (jack_native_thread_t)NULL; return 0; } else { return -1; } } int JackAndroidThread::Stop() { if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackAndroidThread::Stop"); void* status; fStatus = kIdle; // Request for the thread to stop pthread_join(fThread, &status); fThread = (jack_native_thread_t)NULL; return 0; } else { return -1; } } int JackAndroidThread::KillImp(jack_native_thread_t thread) { if (thread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackAndroidThread::Kill"); void* status; pthread_kill(thread, SIGUSR1); pthread_join(thread, &status); return 0; } else { return -1; } } int JackAndroidThread::StopImp(jack_native_thread_t thread) { if (thread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackAndroidThread::Stop"); void* status; pthread_join(thread, &status); return 0; } else { return -1; } } int JackAndroidThread::AcquireRealTime() { return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; } int JackAndroidThread::AcquireSelfRealTime() { return AcquireRealTimeImp(pthread_self(), fPriority); } int JackAndroidThread::AcquireRealTime(int priority) { fPriority = priority; return AcquireRealTime(); } int JackAndroidThread::AcquireSelfRealTime(int priority) { fPriority = priority; return AcquireSelfRealTime(); } int JackAndroidThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) { struct sched_param rtparam; int res; memset(&rtparam, 0, sizeof(rtparam)); rtparam.sched_priority = priority; jack_log("JackAndroidThread::AcquireRealTimeImp priority = %d", priority); #ifndef JACK_ANDROID_REALTIME_SCHED if ((res = pthread_setschedparam(thread, JACK_SCHED_POLICY, &rtparam)) != 0) { jack_error("Cannot use real-time scheduling (RR/%d)" "(%d: %s)", rtparam.sched_priority, res, strerror(res)); return -1; } #else if ((res = android::requestPriority(getpid(), gettid(), priority)) != 0) { jack_log("Failed to get SCHED_FIFO priority pid %d tid %d; error %d", getpid(), gettid(), res); return -1; } #endif return 0; } int JackAndroidThread::DropRealTime() { return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1; } int JackAndroidThread::DropSelfRealTime() { return DropRealTimeImp(pthread_self()); } int JackAndroidThread::DropRealTimeImp(jack_native_thread_t thread) { struct sched_param rtparam; int res; memset(&rtparam, 0, sizeof(rtparam)); rtparam.sched_priority = 0; if ((res = pthread_setschedparam(thread, SCHED_OTHER, &rtparam)) != 0) { jack_error("Cannot switch to normal scheduling priority(%s)", strerror(errno)); return -1; } return 0; } jack_native_thread_t JackAndroidThread::GetThreadID() { return fThread; } bool JackAndroidThread::IsThread() { return pthread_self() == fThread; } void JackAndroidThread::Terminate() { jack_log("JackAndroidThread::Terminate"); pthread_exit(0); } SERVER_EXPORT void ThreadExit() { jack_log("ThreadExit"); pthread_exit(0); } } // end of namespace bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr) { #if defined(_POSIX_PRIORITY_SCHEDULING) && !defined(__APPLE__) int min, max; min = sched_get_priority_min(JACK_SCHED_POLICY); if (min == -1) { jack_error("sched_get_priority_min() failed."); return false; } max = sched_get_priority_max(JACK_SCHED_POLICY); if (max == -1) { jack_error("sched_get_priority_max() failed."); return false; } *min_ptr = min; *max_ptr = max; return true; #else return false; #endif } bool jack_tls_allocate_key(jack_tls_key *key_ptr) { int ret; ret = pthread_key_create(key_ptr, NULL); if (ret != 0) { jack_error("pthread_key_create() failed with error %d", ret); return false; } return true; } bool jack_tls_free_key(jack_tls_key key) { int ret; ret = pthread_key_delete(key); if (ret != 0) { jack_error("pthread_key_delete() failed with error %d", ret); return false; } return true; } bool jack_tls_set(jack_tls_key key, void *data_ptr) { int ret; ret = pthread_setspecific(key, (const void *)data_ptr); if (ret != 0) { jack_error("pthread_setspecific() failed with error %d", ret); return false; } return true; } void *jack_tls_get(jack_tls_key key) { return pthread_getspecific(key); } 1.9.12~dfsg/android/AndroidShm.h0000644000000000000000000000340313214314510015161 0ustar rootroot#ifndef ANDROIDSHM #define ANDROIDSHM #include #include "BnAndroidShm.h" #include #include #include "shm.h" #include "android/Shm.h" //android extension of shm.h namespace android { class AndroidShm : public BnAndroidShm { #define MAX_SHARED_MEMORY_COUNT 257 private: int MemAlloc(unsigned int size); public: virtual ~AndroidShm(); static int instantiate(); virtual int sendCommand(const char* command); virtual int allocShm(const int size); // if negative return value is error virtual int removeShm(const unsigned int index); // shared memory Á¦°Å virtual int isAllocated(const unsigned int index); // allocated ¿©ºÎ È®ÀÎ virtual int setRegistryIndex(const unsigned int index); virtual int getRegistryIndex(); virtual sp InitSemaphore(const char* name); virtual sp getBuffer(int index); //virtual status_t onTransact( // uint32_t code, // const Parcel& data, // Parcel* reply, // uint32_t flags); private: int testGetBuffer(); int testGetBufferByNewProcess(); AndroidShm(); sp mMemHeap[MAX_SHARED_MEMORY_COUNT]; unsigned int mRegistryIndex; // for named semaphore simulation #define MAX_SEMAPHORE_MEMORY_COUNT 300 #define MAX_SEMAPHORE_NAME_LENGTH 300 sp mSemaphore[MAX_SEMAPHORE_MEMORY_COUNT]; char mSemaphoreName[MAX_SEMAPHORE_MEMORY_COUNT][MAX_SEMAPHORE_NAME_LENGTH]; }; }; #endif 1.9.12~dfsg/android/Shm.cpp0000644000000000000000000006705213214314510014225 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2005-2012 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define LOG_TAG "JAMSHMSERVICE" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "BnAndroidShm.h" #include "AndroidShm.h" #include "JackConstants.h" #include #include #include #include #include #include #include #include #include "JackError.h" // remove ALOGI log #define jack_d //#define jack_d ALOGI #define jack_error ALOGE #define MEMORY_SIZE 10*1024 namespace android { jack_shmtype_t Shm::jack_shmtype = shm_ANDROID; /* The JACK SHM registry is a chunk of memory for keeping track of the * shared memory used by each active JACK server. This allows the * server to clean up shared memory when it exits. To avoid memory * leakage due to kill -9, crashes or debugger-driven exits, this * cleanup is also done when a new instance of that server starts. */ /* per-process global data for the SHM interfaces */ jack_shm_id_t Shm::registry_id; /* SHM id for the registry */ jack_shm_fd_t Shm::registry_fd = JACK_SHM_REGISTRY_FD; jack_shm_info_t Shm::registry_info = { JACK_SHM_NULL_INDEX, 0, 0, { MAP_FAILED } }; /* pointers to registry header and array */ jack_shm_header_t *Shm::jack_shm_header = NULL; jack_shm_registry_t *Shm::jack_shm_registry = NULL; char Shm::jack_shm_server_prefix[JACK_SERVER_NAME_SIZE+1] = ""; /* jack_shm_lock_registry() serializes updates to the shared memory * segment JACK uses to keep track of the SHM segments allocated to * all its processes, including multiple servers. * * This is not a high-contention lock, but it does need to work across * multiple processes. High transaction rates and realtime safety are * not required. Any solution needs to at least be portable to POSIX * and POSIX-like systems. * * We must be particularly careful to ensure that the lock be released * if the owning process terminates abnormally. Otherwise, a segfault * or kill -9 at the wrong moment could prevent JACK from ever running * again on that machine until after a reboot. */ #define JACK_SEMAPHORE_KEY 0x282929 #define JACK_SHM_REGISTRY_KEY JACK_SEMAPHORE_KEY #define JACK_REGISTRY_NAME "/jack-shm-registry" int Shm::semid = -1; pthread_mutex_t Shm::mutex = PTHREAD_MUTEX_INITIALIZER; //sp Shm::mShmService; sp Shm::mShmMemBase[JACK_SHM_HEAP_ENOUGH_COUNT] = {0,}; Shm* Shm::ref = NULL; Shm* Shm::Instantiate() { if(Shm::ref == NULL) { jack_d("shm::Instantiate is called"); Shm::ref = new Shm; //AndroidShm::instantiate(); } return ref; } Shm::Shm() { } Shm::~Shm() { } sp Shm::getShmService(){ return interface_cast(defaultServiceManager()->getService(String16("com.samsung.android.jam.IAndroidShm"))); } //sp& Shm::getShmService() { // if (mShmService.get() == 0) { // sp sm = defaultServiceManager(); // sp binder; // do { // binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm")); // if (binder != 0) // break; // ALOGW("CameraService not published, waiting..."); // usleep(500000); // 0.5 s // } while(true); // mShmService = interface_cast(binder); // } // ALOGE_IF(mShmService==0, "no CameraService!?"); // return mShmService; //} void Shm::shm_copy_from_registry (jack_shm_info_t* /*si*/, jack_shm_registry_index_t ) { // not used } void Shm::shm_copy_to_registry (jack_shm_info_t* /*si*/, jack_shm_registry_index_t*) { // not used } void Shm::jack_release_shm_entry (jack_shm_registry_index_t index) { /* the registry must be locked */ jack_shm_registry[index].size = 0; jack_shm_registry[index].allocator = 0; memset (&jack_shm_registry[index].id, 0, sizeof (jack_shm_registry[index].id)); jack_shm_registry[index].fd = 0; } int Shm::release_shm_info (jack_shm_registry_index_t index) { /* must NOT have the registry locked */ if (jack_shm_registry[index].allocator == GetPID()) { if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } jack_release_shm_entry (index); jack_shm_unlock_registry (); jack_d ("release_shm_info: success!"); } else jack_error ("release_shm_info: error!"); return 0; } char* Shm::shm_addr (unsigned int fd) { if(fd >= JACK_SHM_HEAP_ENOUGH_COUNT) { jack_error("ignore to get memory buffer : index[%d] is too big", fd); return NULL; } sp service = Shm::getShmService(); if(service == NULL){ jack_error("shm service is null"); return NULL; } mShmMemBase[fd] = service->getBuffer(fd); if(mShmMemBase[fd] == NULL) { jack_error("fail to get memory buffer"); return NULL; } return ((char *) mShmMemBase[fd]->getBase()); } int Shm::shm_lock_registry (void) { pthread_mutex_lock (&mutex); return 0; } void Shm::shm_unlock_registry (void) { pthread_mutex_unlock (&mutex); } void Shm::release_shm_entry (jack_shm_registry_index_t index) { /* the registry must be locked */ jack_shm_registry[index].size = 0; jack_shm_registry[index].allocator = 0; memset (&jack_shm_registry[index].id, 0, sizeof (jack_shm_registry[index].id)); } void Shm::remove_shm (jack_shm_id_t *id) { int shm_fd = -1; jack_d("remove_id [%s]",(char*)id); if(!strcmp((const char*)id, JACK_REGISTRY_NAME)) { shm_fd = registry_fd; } else { for (int i = 0; i < MAX_SHM_ID; i++) { if(!strcmp((const char*)id, jack_shm_registry[i].id)) { shm_fd = jack_shm_registry[i].fd; break; } } } if (shm_fd >= 0) { sp service = getShmService(); if(service != NULL) { service->removeShm(shm_fd); } else { jack_error("shm service is null"); } } jack_d ("[APA] jack_remove_shm : ok "); } int Shm::access_registry (jack_shm_info_t * ri) { jack_d("access_registry\n"); /* registry must be locked */ sp service = getShmService(); if(service == NULL){ jack_error("shm service is null"); return EINVAL; } int shm_fd = service->getRegistryIndex(); strncpy (registry_id, JACK_REGISTRY_NAME, sizeof (registry_id) - 1); registry_id[sizeof (registry_id) - 1] = '\0'; if(service->isAllocated(shm_fd) == FALSE) { //jack_error ("Cannot mmap shm registry segment (%s)", // strerror (errno)); jack_error ("Cannot mmap shm registry segment"); //close (shm_fd); ri->ptr.attached_at = NULL; registry_fd = JACK_SHM_REGISTRY_FD; return EINVAL; } ri->fd = shm_fd; registry_fd = shm_fd; ri->ptr.attached_at = shm_addr(shm_fd); if(ri->ptr.attached_at == NULL) { ALOGE("attached pointer is null !"); jack_shm_header = NULL; jack_shm_registry = NULL; return 0; } /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; jack_shm_header = (jack_shm_header_t*)(ri->ptr.attached_at); jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); jack_d("jack_shm_header[%p],jack_shm_registry[%p]", jack_shm_header, jack_shm_registry); //close (shm_fd); // steph return 0; } int Shm::GetUID() { return getuid(); } int Shm::GetPID() { return getpid(); } int Shm::jack_shm_lock_registry (void) { // TODO: replace semaphore to mutex pthread_mutex_lock (&mutex); return 0; } void Shm::jack_shm_unlock_registry (void) { // TODO: replace semaphore to mutex pthread_mutex_unlock (&mutex); return; } void Shm::shm_init_registry () { if(jack_shm_header == NULL) return; /* registry must be locked */ memset (jack_shm_header, 0, JACK_SHM_REGISTRY_SIZE); jack_shm_header->magic = JACK_SHM_MAGIC; //jack_shm_header->protocol = JACK_PROTOCOL_VERSION; jack_shm_header->type = jack_shmtype; jack_shm_header->size = JACK_SHM_REGISTRY_SIZE; jack_shm_header->hdr_len = sizeof (jack_shm_header_t); jack_shm_header->entry_len = sizeof (jack_shm_registry_t); for (int i = 0; i < MAX_SHM_ID; ++i) { jack_shm_registry[i].index = i; } } void Shm::set_server_prefix (const char *server_name) { snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), "jack-%d:%s:", GetUID(), server_name); } /* create a new SHM registry segment * * sets up global registry pointers, if successful * * returns: 0 if registry created successfully * nonzero error code if unable to allocate a new registry */ int Shm::create_registry (jack_shm_info_t * ri) { jack_d("create_registry\n"); /* registry must be locked */ int shm_fd = 0; strncpy (registry_id, JACK_REGISTRY_NAME, sizeof (registry_id) - 1); registry_id[sizeof (registry_id) - 1] = '\0'; sp service = getShmService(); if(service == NULL){ jack_error("shm service is null"); return EINVAL; } if((shm_fd = service->allocShm(JACK_SHM_REGISTRY_SIZE)) < 0) { jack_error("Cannot create shm registry segment"); registry_fd = JACK_SHM_REGISTRY_FD; return EINVAL; } service->setRegistryIndex(shm_fd); /* set up global pointers */ ri->fd = shm_fd; ri->index = JACK_SHM_REGISTRY_INDEX; registry_fd = shm_fd; ri->ptr.attached_at = shm_addr(shm_fd); ri->size = JACK_SHM_REGISTRY_SIZE; jack_shm_header = (jack_shm_header_t*)(ri->ptr.attached_at); jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); jack_d("create_registry jack_shm_header[%p], jack_shm_registry[%p]", jack_shm_header, jack_shm_registry); /* initialize registry contents */ shm_init_registry (); //close (shm_fd); // steph return 0; } int Shm::shm_validate_registry () { /* registry must be locked */ if(jack_shm_header == NULL) { return -1; } if ((jack_shm_header->magic == JACK_SHM_MAGIC) //&& (jack_shm_header->protocol == JACK_PROTOCOL_VERSION) && (jack_shm_header->type == jack_shmtype) && (jack_shm_header->size == JACK_SHM_REGISTRY_SIZE) && (jack_shm_header->hdr_len == sizeof (jack_shm_header_t)) && (jack_shm_header->entry_len == sizeof (jack_shm_registry_t))) { return 0; /* registry OK */ } return -1; } int Shm::server_initialize_shm (int new_registry) { int rc; jack_d("server_initialize_shm\n"); if (jack_shm_header) return 0; /* already initialized */ if (shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } rc = access_registry (®istry_info); if (new_registry) { remove_shm (®istry_id); rc = ENOENT; } switch (rc) { case ENOENT: /* registry does not exist */ rc = create_registry (®istry_info); break; case 0: /* existing registry */ if (shm_validate_registry () == 0) break; /* else it was invalid, so fall through */ case EINVAL: /* bad registry */ /* Apparently, this registry was created by an older * JACK version. Delete it so we can try again. */ release_shm (®istry_info); remove_shm (®istry_id); if ((rc = create_registry (®istry_info)) != 0) { //jack_error ("incompatible shm registry (%s)", // strerror (errno)); jack_error ("incompatible shm registry"); //#ifndef USE_POSIX_SHM // jack_error ("to delete, use `ipcrm -M 0x%0.8x'", JACK_SHM_REGISTRY_KEY); //#endif } break; default: /* failure return code */ break; } shm_unlock_registry (); return rc; } // here begin the API int Shm::register_server (const char *server_name, int new_registry) { int i, res = 0; jack_d("register_server new_registry[%d]\n", new_registry); set_server_prefix (server_name); if (server_initialize_shm (new_registry)) return ENOMEM; if (shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } /* See if server_name already registered. Since server names * are per-user, we register the unique server prefix string. */ for (i = 0; i < MAX_SERVERS; i++) { if (strncmp (jack_shm_header->server[i].name, jack_shm_server_prefix, JACK_SERVER_NAME_SIZE) != 0) continue; /* no match */ if (jack_shm_header->server[i].pid == GetPID()) { res = 0; /* it's me */ goto unlock; } /* see if server still exists */ if (kill (jack_shm_header->server[i].pid, 0) == 0) { res = EEXIST; /* other server running */ goto unlock; } /* it's gone, reclaim this entry */ memset (&jack_shm_header->server[i], 0, sizeof (jack_shm_server_t)); } /* find a free entry */ for (i = 0; i < MAX_SERVERS; i++) { if (jack_shm_header->server[i].pid == 0) break; } if (i >= MAX_SERVERS) { res = ENOSPC; /* out of space */ goto unlock; } /* claim it */ jack_shm_header->server[i].pid = GetPID(); strncpy (jack_shm_header->server[i].name, jack_shm_server_prefix, JACK_SERVER_NAME_SIZE - 1); jack_shm_header->server[i].name[JACK_SERVER_NAME_SIZE - 1] = '\0'; unlock: shm_unlock_registry (); return res; } int Shm::unregister_server (const char * /* server_name */) { int i; if (shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } for (i = 0; i < MAX_SERVERS; i++) { if (jack_shm_header->server[i].pid == GetPID()) { memset (&jack_shm_header->server[i], 0, sizeof (jack_shm_server_t)); } } shm_unlock_registry (); return 0; } int Shm::initialize_shm (const char *server_name) { int rc; if (jack_shm_header) return 0; /* already initialized */ set_server_prefix (server_name); if (shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } if ((rc = access_registry (®istry_info)) == 0) { if ((rc = shm_validate_registry ()) != 0) { jack_error ("Incompatible shm registry, " "are jackd and libjack in sync?"); } } shm_unlock_registry (); return rc; } int Shm::initialize_shm_server (void) { // not used return 0; } int Shm::initialize_shm_client (void) { // not used return 0; } int Shm::cleanup_shm (void) { int i; int destroy; jack_shm_info_t copy; if (shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } for (i = 0; i < MAX_SHM_ID; i++) { jack_shm_registry_t* r; r = &jack_shm_registry[i]; memcpy (©, r, sizeof (jack_shm_info_t)); destroy = FALSE; /* ignore unused entries */ if (r->allocator == 0) continue; /* is this my shm segment? */ if (r->allocator == GetPID()) { /* allocated by this process, so unattach and destroy. */ release_shm (©); destroy = TRUE; } else { /* see if allocator still exists */ if (kill (r->allocator, 0)) { if (errno == ESRCH) { /* allocator no longer exists, * so destroy */ destroy = TRUE; } } } if (destroy) { int index = copy.index; if ((index >= 0) && (index < MAX_SHM_ID)) { remove_shm (&jack_shm_registry[index].id); release_shm_entry (index); } r->size = 0; r->allocator = 0; } } shm_unlock_registry (); return TRUE; } jack_shm_registry_t * Shm::get_free_shm_info () { /* registry must be locked */ jack_shm_registry_t* si = NULL; int i; for (i = 0; i < MAX_SHM_ID; ++i) { if (jack_shm_registry[i].size == 0) { break; } } if (i < MAX_SHM_ID) { si = &jack_shm_registry[i]; } return si; } int Shm::shmalloc (const char * /*shm_name*/, jack_shmsize_t size, jack_shm_info_t* si) { jack_shm_registry_t* registry; int shm_fd; int rc = -1; char name[SHM_NAME_MAX+1]; if (shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } sp service = getShmService(); if(service == NULL){ rc = errno; jack_error("shm service is null"); goto unlock; } if ((registry = get_free_shm_info ()) == NULL) { jack_error ("shm registry full"); goto unlock; } snprintf (name, sizeof (name), "/jack-%d-%d", GetUID(), registry->index); if (strlen (name) >= sizeof (registry->id)) { jack_error ("shm segment name too long %s", name); goto unlock; } if((shm_fd = service->allocShm(size)) < 0) { rc = errno; jack_error ("Cannot create shm segment %s", name); goto unlock; } //close (shm_fd); registry->size = size; strncpy (registry->id, name, sizeof (registry->id) - 1); registry->id[sizeof (registry->id) - 1] = '\0'; registry->allocator = GetPID(); registry->fd = shm_fd; si->fd = shm_fd; si->index = registry->index; si->ptr.attached_at = MAP_FAILED; /* not attached */ rc = 0; /* success */ jack_d ("[APA] jack_shmalloc : ok "); unlock: shm_unlock_registry (); return rc; } void Shm::release_shm (jack_shm_info_t* /*si*/) { // do nothing } void Shm::release_lib_shm (jack_shm_info_t* /*si*/) { // do nothing } void Shm::destroy_shm (jack_shm_info_t* si) { /* must NOT have the registry locked */ if (si->index == JACK_SHM_NULL_INDEX) return; /* segment not allocated */ remove_shm (&jack_shm_registry[si->index].id); release_shm_info (si->index); } int Shm::attach_shm (jack_shm_info_t* si) { jack_shm_registry_t *registry = &jack_shm_registry[si->index]; if((si->ptr.attached_at = shm_addr(registry->fd)) == NULL) { jack_error ("Cannot mmap shm segment %s", registry->id); close (si->fd); return -1; } return 0; } int Shm::attach_lib_shm (jack_shm_info_t* si) { int res = attach_shm(si); if (res == 0) si->size = jack_shm_registry[si->index].size; // Keep size in si struct return res; } int Shm::attach_shm_read (jack_shm_info_t* si) { jack_shm_registry_t *registry = &jack_shm_registry[si->index]; if((si->ptr.attached_at = shm_addr(registry->fd)) == NULL) { jack_error ("Cannot mmap shm segment %s", registry->id); close (si->fd); return -1; } return 0; } int Shm::attach_lib_shm_read (jack_shm_info_t* si) { int res = attach_shm_read(si); if (res == 0) si->size = jack_shm_registry[si->index].size; // Keep size in si struct return res; } int Shm::resize_shm (jack_shm_info_t* si, jack_shmsize_t size) { jack_shm_id_t id; /* The underlying type of `id' differs for SYSV and POSIX */ memcpy (&id, &jack_shm_registry[si->index].id, sizeof (id)); release_shm (si); destroy_shm (si); if (shmalloc ((char *) id, size, si)) { return -1; } return attach_shm (si); } void Shm::jack_shm_copy_from_registry (jack_shm_info_t* si, jack_shm_registry_index_t t) { Shm::Instantiate()->shm_copy_from_registry(si,t); } void Shm::jack_shm_copy_to_registry (jack_shm_info_t* si, jack_shm_registry_index_t* t) { Shm::Instantiate()->shm_copy_to_registry(si,t); } int Shm::jack_release_shm_info (jack_shm_registry_index_t t) { return Shm::Instantiate()->release_shm_info(t); } char* Shm::jack_shm_addr (jack_shm_info_t* si) { if(si != NULL) { return (char*)si->ptr.attached_at; } else { jack_error ("jack_shm_addr : jack_shm_info_t is NULL!"); return NULL; } } int Shm::jack_register_server (const char *server_name, int new_registry) { return Shm::Instantiate()->register_server(server_name, new_registry); } int Shm::jack_unregister_server (const char *server_name) { return Shm::Instantiate()->unregister_server(server_name); } int Shm::jack_initialize_shm (const char *server_name) { return Shm::Instantiate()->initialize_shm(server_name); } int Shm::jack_initialize_shm_server (void) { return Shm::Instantiate()->initialize_shm_server(); } int Shm::jack_initialize_shm_client () { return Shm::Instantiate()->initialize_shm_client(); } int Shm::jack_cleanup_shm (void) { return Shm::Instantiate()->cleanup_shm(); } int Shm::jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result) { return Shm::Instantiate()->shmalloc(shm_name, size, result); } void Shm::jack_release_shm (jack_shm_info_t* si) { Shm::Instantiate()->release_shm(si); } void Shm::jack_release_lib_shm (jack_shm_info_t* si) { Shm::Instantiate()->release_lib_shm(si); } void Shm::jack_destroy_shm (jack_shm_info_t* si) { Shm::Instantiate()->destroy_shm(si); } int Shm::jack_attach_shm (jack_shm_info_t* si) { return Shm::Instantiate()->attach_shm(si); } int Shm::jack_attach_lib_shm (jack_shm_info_t* si) { return Shm::Instantiate()->attach_lib_shm(si); } int Shm::jack_attach_shm_read (jack_shm_info_t* si) { return Shm::Instantiate()->attach_shm_read(si); } int Shm::jack_attach_lib_shm_read (jack_shm_info_t* si) { return Shm::Instantiate()->attach_lib_shm_read(si); } int Shm::jack_resize_shm (jack_shm_info_t* si, jack_shmsize_t size) { return Shm::Instantiate()->resize_shm(si, size); } }; void jack_shm_copy_from_registry (jack_shm_info_t* si, jack_shm_registry_index_t t) { android::Shm::jack_shm_copy_from_registry(si, t); } void jack_shm_copy_to_registry (jack_shm_info_t* si, jack_shm_registry_index_t* t) { android::Shm::jack_shm_copy_to_registry(si, t); } int jack_release_shm_info (jack_shm_registry_index_t t) { return android::Shm::jack_release_shm_info(t); } char* jack_shm_addr (jack_shm_info_t* si) { return android::Shm::jack_shm_addr(si); } int jack_register_server (const char *server_name, int new_registry) { return android::Shm::jack_register_server(server_name, new_registry); } int jack_unregister_server (const char *server_name) { return android::Shm::jack_unregister_server(server_name); } int jack_initialize_shm (const char *server_name) { return android::Shm::jack_initialize_shm(server_name); } int jack_initialize_shm_server (void) { return android::Shm::jack_initialize_shm_server(); } int jack_initialize_shm_client (void) { return android::Shm::jack_initialize_shm_client(); } int jack_cleanup_shm (void) { return android::Shm::jack_cleanup_shm(); } int jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result) { return android::Shm::jack_shmalloc(shm_name, size, result); } void jack_release_shm (jack_shm_info_t* si) { android::Shm::jack_release_shm(si); } void jack_release_lib_shm (jack_shm_info_t* si) { android::Shm::jack_release_lib_shm(si); } void jack_destroy_shm (jack_shm_info_t* si) { android::Shm::jack_destroy_shm(si); } int jack_attach_shm (jack_shm_info_t* si) { return android::Shm::jack_attach_shm(si); } int jack_attach_lib_shm (jack_shm_info_t* si) { return android::Shm::jack_attach_lib_shm(si); } int jack_attach_shm_read (jack_shm_info_t* si) { return android::Shm::jack_attach_shm_read(si); } int jack_attach_lib_shm_read (jack_shm_info_t* si) { return android::Shm::jack_attach_lib_shm_read(si); } int jack_resize_shm (jack_shm_info_t* si, jack_shmsize_t size) { return android::Shm::jack_resize_shm(si, size); } void jack_instantiate() { android::AndroidShm::instantiate(); } 1.9.12~dfsg/android/JackSapaProxy.h0000644000000000000000000000274013214314510015653 0ustar rootroot/* Copyright (C) 2014 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSapaProxy__ #define __JackSapaProxy__ #include "JackConstants.h" #include "JackPlatformPlug.h" #include "jack.h" #include "jslist.h" #include #include #define SAPAPROXY_PORT_NUM_FOR_CLIENT 16 namespace Jack { class JackSapaProxy { private: jack_client_t* fClient; jack_port_t *fInputPorts[SAPAPROXY_PORT_NUM_FOR_CLIENT]; jack_port_t *fOutputPorts[SAPAPROXY_PORT_NUM_FOR_CLIENT]; public: unsigned int fCapturePorts; unsigned int fPlaybackPorts; JackSapaProxy(jack_client_t* jack_client, const JSList* params); ~JackSapaProxy(); int Setup(jack_client_t* jack_client); static int Process(jack_nframes_t nframes, void* arg); }; } #endif 1.9.12~dfsg/android/NOTICE0000644000000000000000000013240613214314510013672 0ustar rootroot GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ------------------------------------------------------------------------------- GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ------------------------------------------------------------------------------- opensl_io.c: Android OpenSL input/output module (header) Copyright (c) 2012, Victor Lazzarini All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.9.12~dfsg/android/opensl_io.h0000644000000000000000000000705313214314510015125 0ustar rootroot/* opensl_io.c: Android OpenSL input/output module header Copyright (c) 2012, Victor Lazzarini All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef OPENSL_IO #define OPENSL_IO #include #include #include #include typedef struct threadLock_{ pthread_mutex_t m; pthread_cond_t c; unsigned char s; } threadLock; #ifdef __cplusplus extern "C" { #endif typedef struct opensl_stream { // engine interfaces SLObjectItf engineObject; SLEngineItf engineEngine; // output mix interfaces SLObjectItf outputMixObject; // buffer queue player interfaces SLObjectItf bqPlayerObject; SLPlayItf bqPlayerPlay; SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; SLEffectSendItf bqPlayerEffectSend; // recorder interfaces SLObjectItf recorderObject; SLRecordItf recorderRecord; SLAndroidSimpleBufferQueueItf recorderBufferQueue; // buffer indexes int currentInputIndex; int currentOutputIndex; // current buffer half (0, 1) int currentOutputBuffer; int currentInputBuffer; // buffers short *outputBuffer[2]; short *inputBuffer[2]; // size of buffers int outBufSamples; int inBufSamples; // locks void* inlock; void* outlock; double time; int inchannels; int outchannels; int sr; } OPENSL_STREAM; /* Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size in frames. Returns a handle to the OpenSL stream */ OPENSL_STREAM* android_OpenAudioDevice(int sr, int inchannels, int outchannels, int bufferframes); /* Close the audio device */ void android_CloseAudioDevice(OPENSL_STREAM *p); /* Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read. */ int android_AudioIn(OPENSL_STREAM *p, float *buffer,int size); /* Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written. */ int android_AudioOut(OPENSL_STREAM *p, float *buffer,int size); /* Get the current IO block time in seconds */ double android_GetTimestamp(OPENSL_STREAM *p); #ifdef __cplusplus }; #endif #endif // #ifndef OPENSL_IO 1.9.12~dfsg/android/config.h0000644000000000000000000000126013214314510014375 0ustar rootroot/* Configuration header created by Waf - do not edit */ #ifndef _CONFIG_H_WAF #define _CONFIG_H_WAF /* #define HAVE_SAMPLERATE 0 */ /* #define HAVE_PPOLL 0 */ /* #define HAVE_SNDFILE */ /* #define HAVE_NCURSES 0 */ /* #define HAVE_CELT 0 */ /* #define HAVE_CELT_API_0_11 0 */ /* #define HAVE_CELT_API_0_8 0 */ /* #define HAVE_CELT_API_0_7 0 */ /* #define HAVE_CELT_API_0_5 0 */ /* #define HAVE_READLINE 0 */ #define CLIENT_NUM 32 #define PORT_NUM_FOR_CLIENT 24 #define PORT_NUM 256 #define PORT_NUM_MAX 512 #define ADDON_DIR "/system/lib/jack" #define JACK_LOCATION "/system/bin" #define JACKMP 1 /* #define USE_POSIX_SHM 0 */ /* #define __CLIENTDEBUG__ 1 */ #endif /* _CONFIG_H_WAF */ 1.9.12~dfsg/android/JackGoldfishDriver.cpp0000644000000000000000000001612513214314510017175 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackGoldfishDriver.h" #include "JackDriverLoader.h" #include "JackThreadedDriver.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackCompilerDeps.h" #include #include #include #include #define JACK_GOLDFISH_BUFFER_SIZE 4096 namespace Jack { static char const * const kAudioDeviceName = "/dev/eac"; int JackGoldfishDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_uid, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { jack_log("JackGoldfishDriver::Open"); // Generic JackAudioDriver Open if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { return -1; } mFd = ::open(kAudioDeviceName, O_RDWR); jack_log("JackGoldfishDriver::Open(mFd=%d)", mFd); if (!mBuffer) mBuffer = (short *) malloc(sizeof(short) * JACK_GOLDFISH_BUFFER_SIZE * 2); //JackAudioDriver::SetBufferSize(buffer_size); //JackAudioDriver::SetSampleRate(samplerate); return 0; } int JackGoldfishDriver::Close() { jack_log("JackGoldfishDriver::Close"); // Generic audio driver close int res = JackAudioDriver::Close(); if (mFd >= 0) ::close(mFd); if (mBuffer) { free(mBuffer); mBuffer = NULL; } return res; } int JackGoldfishDriver::Read() { jack_log("JackGoldfishDriver::Read"); for (int i = 0; i < fCaptureChannels; i++) { //silence memset(GetInputBuffer(i), 0, sizeof(jack_default_audio_sample_t) * JACK_GOLDFISH_BUFFER_SIZE /* fEngineControl->fBufferSize */); } return 0; } int JackGoldfishDriver::Write() { jack_log("JackGoldfishDriver::Write"); //write(mFd, GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); jack_default_audio_sample_t* outputBuffer_1 = GetOutputBuffer(0); jack_default_audio_sample_t* outputBuffer_2 = GetOutputBuffer(1); for(int i=0, j=0; ifBufferSize */; i++) { //convert float to short *(mBuffer + j) = (short) (*(outputBuffer_1 + i) * 32640); j++; *(mBuffer + j) = (short) (*(outputBuffer_2 + i) * 32640); j++; } write(mFd, mBuffer, sizeof(short) * JACK_GOLDFISH_BUFFER_SIZE * 2); return 0; } int JackGoldfishDriver::SetBufferSize(jack_nframes_t buffer_size) { jack_log("JackGoldfishDriver::SetBufferSize"); JackAudioDriver::SetBufferSize(buffer_size); return 0; } } // end of namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("goldfish", JackDriverMaster, "Timer based backend", &filler); value.ui = 2U; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamUInt, &value, NULL, "Number of capture ports", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamUInt, &value, NULL, "Number of playback ports", NULL); value.ui = 44100U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "monitor", 'm', JackDriverParamBool, &value, NULL, "Provide monitor ports for the output", NULL); value.ui = JACK_GOLDFISH_BUFFER_SIZE; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = 21333U; jack_driver_descriptor_add_parameter(desc, &filler, "wait", 'w', JackDriverParamUInt, &value, NULL, "Number of usecs to wait between engine processes", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t sample_rate = 44100; jack_nframes_t buffer_size = JACK_GOLDFISH_BUFFER_SIZE; unsigned int capture_ports = 2; unsigned int playback_ports = 2; int wait_time = 0; const JSList * node; const jack_driver_param_t * param; bool monitor = false; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'C': capture_ports = param->value.ui; break; case 'P': playback_ports = param->value.ui; break; case 'r': sample_rate = param->value.ui; break; case 'p': buffer_size = param->value.ui; break; case 'w': wait_time = param->value.ui; break; case 'm': monitor = param->value.i; break; } } if (wait_time > 0) { buffer_size = lroundf((wait_time * sample_rate) / 1000000.0f); if (buffer_size > BUFFER_SIZE_MAX) { buffer_size = BUFFER_SIZE_MAX; jack_error("Buffer size set to %d", BUFFER_SIZE_MAX); } } Jack::JackDriverClientInterface* driver = new Jack::JackThreadedDriver(new Jack::JackGoldfishDriver("system", "goldfish_pcm", engine, table)); if (driver->Open(buffer_size, sample_rate, 1, 1, capture_ports, playback_ports, monitor, "goldfish", "goldfish", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/android/JackSapaProxyIn.cpp0000644000000000000000000000600113214314510016467 0ustar rootroot/* Copyright (C) 2014 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackSapaProxy.h" #include "JackServerGlobals.h" #include "JackEngineControl.h" #include "JackLockedEngine.h" #include "JackArgParser.h" #include #include #ifdef __cplusplus extern "C" { #endif #include "driver_interface.h" using namespace Jack; static Jack::JackSapaProxy* sapaproxy = NULL; SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("in", JackDriverNone, "sapaproxy client", &filler); value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamUInt, &value, NULL, "Number of capture ports", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamUInt, &value, NULL, "Number of playback ports", NULL); return desc; } SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params) { if (sapaproxy) { jack_info("sapaproxy already loaded"); return 1; } jack_log("Loading sapaproxy"); sapaproxy = new Jack::JackSapaProxy(jack_client, params); if (!params) { sapaproxy->fCapturePorts = 2U; sapaproxy->fPlaybackPorts = 0U; } sapaproxy->Setup(jack_client); assert(sapaproxy); return 0; } SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init) { JSList* params = NULL; bool parse_params = true; int res = 1; jack_driver_desc_t* desc = jack_get_descriptor(); Jack::JackArgParser parser(load_init); if (parser.GetArgc() > 0) parse_params = parser.ParseParams(desc, ¶ms); if (parse_params) { res = jack_internal_initialize(jack_client, params); parser.FreeParams(params); } return res; } SERVER_EXPORT void jack_finish(void* arg) { Jack::JackSapaProxy* sapaproxy = static_cast(arg); if (sapaproxy) { jack_log("Unloading sapaproxy"); delete sapaproxy; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/android/BnAndroidShm.h0000644000000000000000000000055413214314510015445 0ustar rootroot#ifndef BNANDROIDSHM #define BNANDROIDSHM #include #include "IAndroidShm.h" namespace android { class BnAndroidShm : public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; #endif 1.9.12~dfsg/android/JackCompilerDeps_os.h0000644000000000000000000000273013214314510017013 0ustar rootroot/* Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackCompilerDeps_android__ #define __JackCompilerDeps_android__ #include "JackConstants.h" #if __GNUC__ #define MEM_ALIGN(x,y) x __attribute__((aligned(y))) #define LIB_EXPORT __attribute__((visibility("default"))) #ifdef SERVER_SIDE #if (__GNUC__< 4) #define SERVER_EXPORT #else #define SERVER_EXPORT __attribute__((visibility("default"))) #endif #else #define SERVER_EXPORT __attribute__((visibility("hidden"))) #endif #else #define MEM_ALIGN(x,y) x #define LIB_EXPORT #define SERVER_EXPORT /* Add other things here for non-gcc platforms */ #endif #endif /* __JackCompilerDeps_android__ */ 1.9.12~dfsg/android/JackOpenSLESDriver.cpp0000644000000000000000000001750013214314510017024 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackOpenSLESDriver.h" #include "JackDriverLoader.h" #include "JackThreadedDriver.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackCompilerDeps.h" #include #include #include #include #include #include "opensl_io.h" #define JACK_OPENSLES_DEFAULT_SAMPLERATE 48000 #define JACK_OPENSLES_DEFAULT_BUFFER_SIZE 960 namespace Jack { static OPENSL_STREAM *pOpenSL_stream; int JackOpenSLESDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_uid, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { jack_log("JackOpenSLESDriver::Open"); // Generic JackAudioDriver Open if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { return -1; } if (capturing) { inbuffer = (float *) malloc(sizeof(float) * buffer_size); //mono input memset(inbuffer, 0, sizeof(float) * buffer_size); } if (playing) { outbuffer = (float *) malloc(sizeof(float) * buffer_size * 2); //stereo output memset(outbuffer, 0, sizeof(float) * buffer_size * 2); } pOpenSL_stream = android_OpenAudioDevice(samplerate, capturing ? 1 : 0, playing ? 2 : 0, buffer_size); if (pOpenSL_stream == NULL) return -1; return 0; } int JackOpenSLESDriver::Close() { jack_log("JackOpenSLESDriver::Close"); // Generic audio driver close int res = JackAudioDriver::Close(); android_CloseAudioDevice(pOpenSL_stream); if (inbuffer) { free(inbuffer); inbuffer = NULL; } if (outbuffer) { free(outbuffer); outbuffer = NULL; } return res; } int JackOpenSLESDriver::Read() { //jack_log("JackOpenSLESDriver::Read"); jack_default_audio_sample_t* inputBuffer_1 = GetInputBuffer(0); jack_default_audio_sample_t* inputBuffer_2 = GetInputBuffer(1); if (inbuffer) { int samps = android_AudioIn(pOpenSL_stream,inbuffer,fEngineControl->fBufferSize); for (int i = 0; i < samps; i++) { *(inputBuffer_1 + i) = *(inbuffer + i); *(inputBuffer_2 + i) = *(inbuffer + i); } } else { for (int i = 0; i < fCaptureChannels; i++) { memset(GetInputBuffer(i), 0, sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); //silence } } return 0; } int JackOpenSLESDriver::Write() { //jack_log("JackOpenSLESDriver::Write"); jack_default_audio_sample_t* outputBuffer_1 = GetOutputBuffer(0); jack_default_audio_sample_t* outputBuffer_2 = GetOutputBuffer(1); if (outbuffer) { android_AudioOut(pOpenSL_stream, outbuffer, fEngineControl->fBufferSize * 2); //stereo output for (unsigned int i = 0, j = 0; i < fEngineControl->fBufferSize; i++) { *(outbuffer + j) = *(outputBuffer_1 + i); j++; *(outbuffer + j) = *(outputBuffer_2 + i); j++; } } return 0; } int JackOpenSLESDriver::SetBufferSize(jack_nframes_t buffer_size) { jack_log("JackOpenSLESDriver::SetBufferSize"); JackAudioDriver::SetBufferSize(buffer_size); return 0; } } // end of namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("opensles", JackDriverMaster, "Timer based backend", &filler); value.ui = 2U; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamUInt, &value, NULL, "Number of capture ports", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamUInt, &value, NULL, "Number of playback ports", NULL); value.ui = 48000U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "monitor", 'm', JackDriverParamBool, &value, NULL, "Provide monitor ports for the output", NULL); value.ui = JACK_OPENSLES_DEFAULT_BUFFER_SIZE; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = 21333U; jack_driver_descriptor_add_parameter(desc, &filler, "wait", 'w', JackDriverParamUInt, &value, NULL, "Number of usecs to wait between engine processes", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t sample_rate = JACK_OPENSLES_DEFAULT_SAMPLERATE; jack_nframes_t buffer_size = JACK_OPENSLES_DEFAULT_BUFFER_SIZE; unsigned int capture_ports = 0; unsigned int playback_ports = 2; int wait_time = 0; const JSList * node; const jack_driver_param_t * param; bool monitor = false; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'C': capture_ports = param->value.ui; break; case 'P': playback_ports = param->value.ui; break; case 'r': sample_rate = param->value.ui; break; case 'p': buffer_size = param->value.ui; break; case 'w': wait_time = param->value.ui; break; case 'm': monitor = param->value.i; break; } } if (wait_time > 0) { buffer_size = lroundf((wait_time * sample_rate) / 1000000.0f); if (buffer_size > BUFFER_SIZE_MAX) { buffer_size = BUFFER_SIZE_MAX; jack_error("Buffer size set to %d", BUFFER_SIZE_MAX); } } Jack::JackDriverClientInterface* driver = new Jack::JackThreadedDriver(new Jack::JackOpenSLESDriver("system", "opensles_pcm", engine, table)); if (driver->Open(buffer_size, sample_rate, capture_ports? 1 : 0, playback_ports? 1 : 0, capture_ports, playback_ports, monitor, "opensles", "opensles", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/android/BnAndroidShm.cpp0000644000000000000000000000531413214314510015777 0ustar rootroot#include "BnAndroidShm.h" #include namespace android { status_t BnAndroidShm::onTransact( uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { switch(code) { case HW_SENDCOMMAND:{ CHECK_INTERFACE(IAndroidShm, data, reply); const char *str; str = data.readCString(); reply->writeInt32(sendCommand(str)); return NO_ERROR; }break; case HW_GETBUFFER:{ CHECK_INTERFACE(IAndroidShm, data, reply); int32_t index; data.readInt32(&index); sp Data = getBuffer(index); if(Data != NULL){ reply->writeStrongBinder(Data->asBinder()); } return NO_ERROR; }break; case HW_ALLOC_SHM:{ CHECK_INTERFACE(IAndroidShm, data, reply); int32_t size; data.readInt32(&size); reply->writeInt32(allocShm(size)); return NO_ERROR; }break; case HW_REMOVE_SHM:{ CHECK_INTERFACE(IAndroidShm, data, reply); int32_t index; data.readInt32(&index); reply->writeInt32(removeShm(index)); return NO_ERROR; }break; case HW_IS_ALLOCATED:{ CHECK_INTERFACE(IAndroidShm, data, reply); int32_t index; data.readInt32(&index); reply->writeInt32(isAllocated(index)); return NO_ERROR; }break; case HW_SET_REGISTRY_INDEX:{ CHECK_INTERFACE(IAndroidShm, data, reply); int32_t index; data.readInt32(&index); reply->writeInt32(setRegistryIndex(index)); return NO_ERROR; }break; case HW_GET_REGISTRY_INDEX:{ CHECK_INTERFACE(IAndroidShm, data, reply); reply->writeInt32(getRegistryIndex()); return NO_ERROR; }break; case HW_INIT_SEMAPHORE:{ CHECK_INTERFACE(IAndroidShm, data, reply); const char *name; name = data.readCString(); sp Data = InitSemaphore(name); if(Data != NULL){ reply->writeStrongBinder(Data->asBinder()); } return NO_ERROR; }break; default: return BBinder::onTransact(code, data, reply, flags); } } }; 1.9.12~dfsg/android/JackControlAPIAndroid.h0000644000000000000000000000216013214314510017174 0ustar rootroot/* JACK control API Copyright (C) 2008 Nedko Arnaudov Copyright (C) 2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackControlAPIAndroid__ #define __JackControlAPIAndroid__ #include "JackCompilerDeps.h" /** opaque type for sigmask object */ typedef struct jackctl_sigmask jackctl_sigmask_t; #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT int jackctl_wait_signals_and_return( jackctl_sigmask_t * signals); #ifdef __cplusplus } /* extern "C" */ #endif #endif 1.9.12~dfsg/android/AndroidShmServer/0000755000000000000000000000000013214314510016177 5ustar rootroot1.9.12~dfsg/android/AndroidShmServer/main_androidshmservice.cpp0000644000000000000000000000073413214314510023424 0ustar rootroot#define LOG_TAG "main_androidshmservice" #include #include #include #include #include "../../common/shm.h" #include "../Shm.h" //android extension of shm.h using namespace android; int main(int argc, char *argv[]) { jack_instantiate(); ProcessState::self()->startThreadPool(); ALOGI("AndroidShmService is starting now"); IPCThreadState::self()->joinThreadPool(); return 0; } 1.9.12~dfsg/android/AndroidShmServer/test/0000755000000000000000000000000013214314510017156 5ustar rootroot1.9.12~dfsg/android/AndroidShmServer/test/shmservicetest.cpp0000644000000000000000000001136313214314510022736 0ustar rootroot#include "../../IAndroidShm.h" #include #include namespace android { static sp receiverMemBase; #define MAX_SHARED_MEMORY_COUNT 257 sp getAndroidShmService() { sp shm = 0; /* Get the buffer service */ if (shm == NULL) { sp sm = defaultServiceManager(); sp binder; binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm")); if (binder != 0) { shm = IAndroidShm::asInterface(binder); //shm = interface_cast(binder); } } return shm; } unsigned int * getBufferMemPointer(int index) { sp shm = getAndroidShmService(); if (shm == NULL) { ALOGE("The EneaBufferServer is not published"); return (unsigned int *)-1; /* return an errorcode... */ } else { receiverMemBase = shm->getBuffer(index); if(receiverMemBase != NULL) return (unsigned int *) receiverMemBase->getBase(); else return (unsigned int*)-1; } } } using namespace android; void setup_test() { sp shm = getAndroidShmService(); if(shm == NULL) return; for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) { shm->removeShm(i); } } void teardown_test() { } void increase_value_once() { ALOGD("*****test: increase_value_once*****\n"); sp shm = getAndroidShmService(); if(shm == NULL) return; int slot = shm->allocShm(10000); unsigned int *base = getBufferMemPointer(slot); if(base != (unsigned int *)-1) { ALOGD("ShmServiceTest base=%p Data=0x%x\n",base, *base); *base = (*base)+1; ALOGD("ShmServiceTest base=%p Data=0x%x CHANGED\n",base, *base); //receiverMemBase = 0; } else { ALOGE("Error shared memory not available\n"); } } void increase_value_10times() { ALOGD("*****test: increase_value_10times*****\n"); sp shm = getAndroidShmService(); if(shm == NULL) return; int slot = shm->allocShm(10000); for(int i = 0; i < 10; i++) { unsigned int *base = getBufferMemPointer(slot); if(base != (unsigned int *)-1) { ALOGD("ShmServiceTest base=%p Data=0x%x\n",base, *base); *base = (*base)+1; ALOGD("ShmServiceTest base=%p Data=0x%x CHANGED\n",base, *base); //receiverMemBase = 0; } else { ALOGE("Error shared memory not available\n"); } } } void check_allocated() { ALOGD("*****test: check_allocated*****\n"); sp shm = getAndroidShmService(); if(shm == NULL) return; int slot = shm->allocShm(10000); int i = 0; for(; i < MAX_SHARED_MEMORY_COUNT; i++) { if(slot == i) { if(shm->isAllocated(i) == 1) { //ALOGD("pass\n"); } else { ALOGD("failed\n"); } } else { if(shm->isAllocated(i) == 0) { //ALOGD("pass\n"); } else { ALOGD("failed\n"); } } } if(i == MAX_SHARED_MEMORY_COUNT) { ALOGD("pass\n"); } } void test_set_get_registry_index() { ALOGD("*****test: test_set_get_registry_index*****\n"); sp shm = getAndroidShmService(); if(shm == NULL) return; int registry = 1; shm->setRegistryIndex(registry); if(registry == shm->getRegistryIndex()) { ALOGD("pass\n"); } else { ALOGD("fail\n"); } registry = 0; shm->setRegistryIndex(registry); if(registry == shm->getRegistryIndex()) { ALOGD("pass\n"); } else { ALOGD("fail\n"); } } void test_memset() { ALOGD("*****test: test_memset*****\n"); sp shm = getAndroidShmService(); if(shm == NULL) return; int slot = shm->allocShm(10000); unsigned int * pnt = getBufferMemPointer(slot); memset (pnt, 0, 10000); ALOGD("result : 0 0 0 0\n"); ALOGD("memory dump : %d %d %d %d\n", pnt[0], pnt[1], pnt[2], pnt[3]); memset (pnt, 0xffffffff, 10000); ALOGD("result : -1 -1 -1 -1\n"); ALOGD("memory dump : %d %d %d %d", pnt[0], pnt[1], pnt[2], pnt[3]); } int main(int argc, char** argv) { // base could be on same address as Servers base but this // is purely by luck do NEVER rely on this. Linux memory // management may put it wherever it likes. setup_test(); increase_value_once(); teardown_test(); setup_test(); increase_value_10times(); teardown_test(); setup_test(); check_allocated(); teardown_test(); setup_test(); test_set_get_registry_index(); teardown_test(); setup_test(); test_memset(); teardown_test(); return 0; } 1.9.12~dfsg/android/AndroidShmServer/test/shmservicedump.cpp0000644000000000000000000001245213214314510022724 0ustar rootroot#include "../../IAndroidShm.h" #include #include #include "../../../common/shm.h" namespace android { static sp receiverMemBase; #define MAX_SHARED_MEMORY_COUNT 257 sp getAndroidShmService() { sp shm = 0; /* Get the buffer service */ if (shm == NULL) { sp sm = defaultServiceManager(); sp binder; binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm")); if (binder != 0) { shm = IAndroidShm::asInterface(binder); //shm = interface_cast(binder); } } return shm; } unsigned int * getBufferMemPointer(int index) { sp shm = getAndroidShmService(); if (shm == NULL) { printf("The EneaBufferServer is not published\n"); return (unsigned int *)-1; /* return an errorcode... */ } else { receiverMemBase = shm->getBuffer(index); if(receiverMemBase != NULL) return (unsigned int *) receiverMemBase->getBase(); else return (unsigned int*)-1; } } } using namespace android; void showStatus() { sp shm = getAndroidShmService(); if(shm == NULL) { printf("shm service is not available\n"); return; } printf("<<<<<<<<<<< dump memory allocation status >>>>>>>>>>\n"); for(int i = 256; i >= 0; i--) { if(shm->isAllocated(i) == 1) { printf("Mem[%3d] == 0x%x\n", i, (unsigned int)getBufferMemPointer(i)); } else { printf("Mem[%3d] == NULL\n", i); } } } void showRegistryIndex() { sp shm = getAndroidShmService(); if(shm == NULL) { printf("shm service is not available\n"); return; } printf("<<<<<<<<<<< show registry index >>>>>>>>>>\n"); printf("index [%3d]\n",shm->getRegistryIndex()); } void showHeader() { sp shm = getAndroidShmService(); if(shm == NULL) { printf("shm service is not available\n"); return; } if(shm->getRegistryIndex() > 256) { printf("don't have a registry header\n"); return; } unsigned int* buffer = getBufferMemPointer(shm->getRegistryIndex()); if(buffer) { jack_shm_header_t * header = (jack_shm_header_t*)buffer; printf("<<<<<<<<<< register header value >>>>>>>>>>\n"); printf("memory address 0x%x 0x%x\n", (unsigned int)(header), (unsigned int)buffer); printf("magic = %d\n", header->magic); printf("protocol = %d\n", header->protocol); printf("type = %d\n", header->type); printf("size = %d\n", header->size); printf("hdr_len = %d\n", header->hdr_len); printf("entry_len = %d\n", header->entry_len); for(int j = 0; j < MAX_SERVERS; j++) { //char name[256]; //memset(name, '\0', 256); //strncpy(name, header->server[j].name, 10); printf("server[%d] pid = %d, name = %s\n", j, header->server[j].pid, header->server[j].name); } } } void showBody() { sp shm = getAndroidShmService(); if(shm == NULL) { printf("shm service is not available\n"); return; } if(shm->getRegistryIndex() > 256) { printf("don't have a registry body\n"); return; } unsigned int* buffer = getBufferMemPointer(shm->getRegistryIndex()); if(buffer) { jack_shm_header_t * header = (jack_shm_header_t*)buffer; printf("<<<<<<<<<< registry body value >>>>>>>>>>\n"); jack_shm_registry_t * registry = (jack_shm_registry_t *) (header + 1); for(int k = 255; k >= 0; k--) { printf("registry[%3d] index[%3d],allocator[%3d],size[%6d],id[%10s],fd[%3d]\n", k, registry[k].index, registry[k].allocator, registry[k].size, registry[k].id, registry[k].fd); } } } void showSemaphore() { sp shm = getAndroidShmService(); if(shm == NULL) { printf("shm service is not available\n"); return; } shm->sendCommand("semaphore"); printf("log will be shown in the logcat log\n"); } int main(int argc, char** argv) { // base could be on same address as Servers base but this // is purely by luck do NEVER rely on this. Linux memory // management may put it wherever it likes. if(argc < 2) { printf("usage\n shmservicedump [status|header|body|index|semaphore]\n"); printf(" status: show the shared memory allocation status\n"); printf(" header: show the registry header infomations if the registry exist\n"); printf(" body: show the registry body infomations if the registry exist\n"); printf(" index: show the index of array that is allocated registry shared memory\n"); printf(" semaphore: show the memory array about semaphore simulation\n"); return 0; } if(strcmp(argv[1], "semaphore") == 0) { showSemaphore(); } else if(strcmp(argv[1], "index") == 0) { showRegistryIndex(); } else if(strcmp(argv[1], "status") == 0) { showStatus(); } else if(strcmp(argv[1], "header") == 0) { showHeader(); } else if(strcmp(argv[1], "body") == 0) { showBody(); } else { printf("%s is invalid parameter\n", argv[1]); } return 0; } 1.9.12~dfsg/android/AndroidShmServer/readme.txt0000644000000000000000000000102113214314510020167 0ustar rootrootIAndroidShmÀÇ ±â´ÉÀ» Å×½ºÆ® Çϱâ À§ÇÑ ¿ëµµ·Î »ç¿ëµÇ´Â ÇÁ·Î±×·¥ÀÔ´Ï´Ù. AndroidShmÀº service manager¿¡ shared memory¸¦ ÇÒ´çÇØÁÖ´Â ¼­ºñ½ºÀÔ´Ï´Ù. service name: com.sec.apa.IAndroidShm ½ÇÇà ÆÄÀÏ: /system/bin/androidshmservice ------------------------------------------- ./test AndroidShmService¸¦ Å×½ºÆ®ÇÏ´Â ÇÁ·Î±×·¥ /system/bin/shmservicetest AndroidShmService¿¡¼­ Á¦°øÇÏ´Â ±â´ÉÀ» UnitTestÇÕ´Ï´Ù. µ¿ÀÛ È®ÀÎ ¹æ¹ý: adb logcat À¸·Î ·Î±×·Î ¼º°ø/½ÇÆÐ È®ÀÎÇÔ. ÀüÁ¦ Á¶°Ç: /system/bin/androidshmservice¸¦ ½ÇÇàÁßÀÎ »óÅÂÀ̾î¾ß ÇÕ´Ï´Ù.1.9.12~dfsg/android/JackError.cpp0000644000000000000000000000772013214314510015354 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2008 Nedko Arnaudov Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "JackError.h" #include "JackGlobals.h" #include "JackMessageBuffer.h" #define LOG_BUF_SIZE 1024 #undef LOG_TAG #ifdef SERVER_SIDE #define LOG_TAG "JackAudioServer" #else #define LOG_TAG "JackAudioClient" #endif #include using namespace Jack; static bool change_thread_log_function(jack_log_function_t log_function) { return (jack_tls_get(JackGlobals::fKeyLogFunction) == NULL && jack_tls_set(JackGlobals::fKeyLogFunction, (void*)log_function)); } SERVER_EXPORT int set_threaded_log_function() { return change_thread_log_function(JackMessageBufferAdd); } void jack_log_function(int level, const char *message) { void (* log_callback)(const char *); switch (level) { case LOG_LEVEL_INFO: log_callback = jack_info_callback; break; case LOG_LEVEL_ERROR: log_callback = jack_error_callback; break; default: return; } log_callback(message); } static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) { char buffer[256]; size_t len; jack_log_function_t log_function; if (prefix != NULL) { len = strlen(prefix); assert(len < 256); memcpy(buffer, prefix, len); } else { len = 0; } vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap); log_function = (jack_log_function_t)jack_tls_get(JackGlobals::fKeyLogFunction); /* if log function is not overriden for thread, use default one */ if (log_function == NULL) { log_function = jack_log_function; //log_function(LOG_LEVEL_INFO, "------ Using default log function"); } else { //log_function(LOG_LEVEL_INFO, "++++++ Using thread-specific log function"); } log_function(level, buffer); } SERVER_EXPORT void jack_error(const char *fmt, ...) { va_list ap; char buf[LOG_BUF_SIZE]; va_start(ap, fmt); vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); va_end(ap); __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, buf); } SERVER_EXPORT void jack_info(const char *fmt, ...) { va_list ap; char buf[LOG_BUF_SIZE]; va_start(ap, fmt); vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); va_end(ap); __android_log_write(ANDROID_LOG_INFO, LOG_TAG, buf); } SERVER_EXPORT void jack_log(const char *fmt,...) { va_list ap; char buf[LOG_BUF_SIZE]; if (JackGlobals::fVerbose) { va_start(ap, fmt); vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); va_end(ap); __android_log_write(ANDROID_LOG_VERBOSE, LOG_TAG, buf); } } SERVER_EXPORT void default_jack_error_callback(const char *desc) { fprintf(stderr, "%s\n", desc); fflush(stderr); } SERVER_EXPORT void default_jack_info_callback(const char *desc) { fprintf(stdout, "%s\n", desc); fflush(stdout); } SERVER_EXPORT void silent_jack_error_callback(const char *desc) {} SERVER_EXPORT void silent_jack_info_callback(const char *desc) {} SERVER_EXPORT void (*jack_error_callback)(const char *desc) = &default_jack_error_callback; SERVER_EXPORT void (*jack_info_callback)(const char *desc) = &default_jack_info_callback; 1.9.12~dfsg/android/JackAndroidSemaphore.h0000644000000000000000000000374513214314510017157 0ustar rootroot/* Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAndroidSemaphore__ #define __JackAndroidSemaphore__ #include "JackSynchro.h" #include "JackCompilerDeps.h" #include #include #include #include #include #include namespace Jack { /*! \brief Inter process synchronization using POSIX semaphore. */ class SERVER_EXPORT JackAndroidSemaphore : public detail::JackSynchro { private: sem_t* fSemaphore; android::sp fSemaphoreMemory; static pthread_mutex_t mutex; protected: void BuildName(const char* name, const char* server_name, char* res, int size); public: JackAndroidSemaphore():JackSynchro(), fSemaphore(NULL) {} bool Signal(); bool SignalAll(); bool Wait(); bool TimedWait(long usec); bool Allocate(const char* name, const char* server_name, int value); bool Connect(const char* name, const char* server_name); bool ConnectInput(const char* name, const char* server_name); bool ConnectOutput(const char* name, const char* server_name); bool Disconnect(); void Destroy(); }; } // end of namespace #endif 1.9.12~dfsg/android/JackAndroidThread.h0000644000000000000000000000634013214314510016435 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAndroidThread__ #define __JackAndroidThread__ #include "JackThread.h" #include namespace Jack { /* use 512KB stack per thread - the default is way too high to be feasible * with mlockall() on many systems */ #define THREAD_STACK 524288 enum { PTHREAD_CANCEL_DEFERRED, PTHREAD_CANCEL_ASYNCHRONOUS }; /*! \brief The POSIX thread base class. */ class SERVER_EXPORT JackAndroidThread : public detail::JackThreadInterface { protected: jack_native_thread_t fThread; static void* ThreadHandler(void* arg); static void thread_exit_handler(int sig); public: JackAndroidThread(JackRunnableInterface* runnable, bool real_time, int priority, int cancellation) : JackThreadInterface(runnable, priority, real_time, cancellation), fThread((jack_native_thread_t)NULL) {} JackAndroidThread(JackRunnableInterface* runnable, int cancellation = PTHREAD_CANCEL_ASYNCHRONOUS) : JackThreadInterface(runnable, 0, false, cancellation), fThread((jack_native_thread_t)NULL) {} int Start(); int StartSync(); int Kill(); int Stop(); void Terminate(); int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself jack_native_thread_t GetThreadID(); bool IsThread(); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) { return JackAndroidThread::AcquireRealTimeImp(thread, priority); } static int DropRealTimeImp(jack_native_thread_t thread); static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); static int StopImp(jack_native_thread_t thread); static int KillImp(jack_native_thread_t thread); }; SERVER_EXPORT void ThreadExit(); } // end of namespace #endif 1.9.12~dfsg/android/JackControlAPIAndroid.cpp0000644000000000000000000000435413214314510017536 0ustar rootroot// u/* -*- Mode: C++ ; c-basic-offset: 4 -*- */ /* JACK control API implementation Copyright (C) 2008 Nedko Arnaudov Copyright (C) 2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef WIN32 #include #include #include #endif #include "types.h" #include #include #include #include #include #include "JackControlAPIAndroid.h" #include "JackConstants.h" #include "JackServerGlobals.h" using namespace Jack; struct jackctl_sigmask { sigset_t signals; }; static jackctl_sigmask sigmask; SERVER_EXPORT int jackctl_wait_signals_and_return(jackctl_sigmask_t * sigmask) { int sig; bool waiting = true; while (waiting) { #if defined(sun) && !defined(__sun__) // SUN compiler only, to check sigwait(&sigmask->signals); #else sigwait(&sigmask->signals, &sig); #endif fprintf(stderr, "Jack main caught signal %d\n", sig); switch (sig) { case SIGUSR1: //jack_dump_configuration(engine, 1); break; case SIGUSR2: // driver exit waiting = false; break; case SIGTTOU: break; default: waiting = false; break; } } if (sig != SIGSEGV) { // unblock signals so we can see them during shutdown. // this will help prod developers not to lose sight of // bugs that cause segfaults etc. during shutdown. sigprocmask(SIG_UNBLOCK, &sigmask->signals, 0); } return sig; } 1.9.12~dfsg/android/CleanSpec.mk0000644000000000000000000001333113214314510015147 0ustar rootroot $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/common) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/alsa_in_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/alsa_out_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/androidshmservice_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/shmservicetest_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/shmservicedump_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_samplerate_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_freewheel_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_connect_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_disconnect_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_latent_client_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_midiseq_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_zombie_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_lsp_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_load_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jackd_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_monitor_client_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_looper_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_client_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_cpu_load_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_iodelay_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_midisine_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_cpu_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_keyboard_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_unload_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_wait_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_alias_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_metro_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_bufsize_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_thru_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_session_notify_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_midi_latency_test_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_rec_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_netsource_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_net_master_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_net_slave_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_showtime_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_server_control_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_evmon_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_test_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_transport_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_session_client_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_simple_effect_intermediates) $(call add_clean_step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_multiple_metro_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/jack_midi_dump_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/common) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/posix) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjack_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjacknet_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjackserver_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjackshm_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_alsa_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_dummy_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_net_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_loopback_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_netone_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/audioadapter_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/inprocess_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/netadapter_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/netmanager_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/profiler_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_goldfish_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/jack_opensles_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/in_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/out_intermediates) 1.9.12~dfsg/android/AndroidShm.cpp0000644000000000000000000001765113214314510015526 0ustar rootroot#define LOG_TAG "JAMSHMSERVICE" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "BnAndroidShm.h" #include "AndroidShm.h" #include "JackConstants.h" #include #include #include #include #include #include #include #include #include "JackError.h" #include #define MEMORY_SIZE 10*1024 #define SEMAPHORE_NULL_CHAR '\0' // remove ALOGI log #undef ALOGI #define ALOGI namespace android { int AndroidShm::instantiate() { defaultServiceManager()->addService(String16("com.samsung.android.jam.IAndroidShm"), new AndroidShm); // SINGLETON WITH SAME NAME return 0; } int AndroidShm::sendCommand(const char* command) { ALOGI("I(pid:%d) send command is %s\n", getpid(), command); if(strcmp(command, "semaphore") == 0) { // print debug message about semaphore simulation for(int i = MAX_SEMAPHORE_MEMORY_COUNT -1 ; i >= 0; i--) { printf("index[%3d] = ptr[%p] name[%s]\n", i, (mSemaphore[i] != NULL)?mSemaphore[i]->getBase():0, mSemaphoreName[i]); ALOGI("index[%3d] = ptr[%p] name[%s]\n", i, (mSemaphore[i] != NULL)?mSemaphore[i]->getBase():0, mSemaphoreName[i]); } } return NO_ERROR; } int AndroidShm::testGetBufferByNewProcess() { ALOGI("testGetBufferByNewProcess..."); int status; int childPid = fork(); if(childPid > 0) { ALOGI("I(pid%d) made a child process(pid:%d)", getpid(), childPid); ALOGI("I(pid%d) wait until child(%d) was finish", getpid(), childPid); wait(&status); // wait ÇÏÁö ¾ÊÀ¸¸é child process°¡ ³²¾Æ ÀÖÀ½. ALOGI("child(%d) was finished. ", childPid); } else if(childPid == 0) { ALOGI("im a new child process(pid:%d) ", getpid()); if(-1 == execlp("/system/bin/getbufferclient","getbufferclient",NULL)) { ALOGE("failed to execute getbufferclient"); } exit(0); } else { ALOGI("failed creating child process"); } return 0; } int AndroidShm::testGetBuffer() { ALOGI("I(pid:%d) trying to test get buffer...", getpid()); sp sm = defaultServiceManager(); ALOGI("get default ServiceManager is done"); sp b; //String16* serviceName = new String16("com.samsung.android.jam.IAndroidShm"); do { //ALOGI("here"); b = sm->getService(String16("com.samsung.android.jam.IAndroidShm")); //ALOGI("getservice is done"); if(b != 0) break; //ALOGI("AndroidShm is not working, waiting..."); usleep(500000); } while(true); sp service = interface_cast(b); //shared buffer. sp receiverMemBase = service->getBuffer(0); unsigned int *base = (unsigned int *) receiverMemBase->getBase(); int ret = 0; if(base != (unsigned int *) -1) { ALOGD("AndroidShm::testGetBuffer base=%p Data=0x%x\n",base, *base); *base = (*base)+1; ret = (unsigned int)(*base); ALOGI("AndroidShm::testGetBuffer base=%p Data=0x%x CHANGED\n",base, *base); receiverMemBase = 0; } else { ALOGE("Error shared memory not available\n"); } return 0; } sp AndroidShm::getBuffer(int index) { ALOGI("I(pid:%d) getBuffer index:%d", getpid(), index); if(index < 0 || index >= MAX_SHARED_MEMORY_COUNT) { ALOGE("error : out of index [%d]", index); return NULL; } return mMemHeap[index]; } int AndroidShm::MemAlloc(unsigned int size) { ALOGI("try to allocate memory size[%d]", size); for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) { if(mMemHeap[i] == NULL) { mMemHeap[i] = new MemoryHeapBase(size); if(mMemHeap[i] == NULL){ ALOGI("fail to alloc, try one more..."); continue; // try one more. } return i; } } ALOGE("fail to MemAlloc"); return -1; // fail to alloc } AndroidShm::AndroidShm() { ALOGI("AndroidShm is created"); for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) { mMemHeap[i] = NULL; } mRegistryIndex = 10000; //mMemHeap = new MemoryHeapBase(MEMORY_SIZE); //unsigned int *base = (unsigned int*) mMemHeap->getBase(); //*base = 0xdeadcafe;// for(int j = 0; j < MAX_SEMAPHORE_MEMORY_COUNT; j++) { mSemaphore[j] = NULL; memset(mSemaphoreName[j], SEMAPHORE_NULL_CHAR, MAX_SEMAPHORE_NAME_LENGTH); } } AndroidShm::~AndroidShm() { ALOGI("AndroidShm is destroyed"); for(int i = 0; i < MAX_SHARED_MEMORY_COUNT; i++) { (mMemHeap[i]).clear(); } for(int j = 0; j < MAX_SEMAPHORE_MEMORY_COUNT; j++) { (mSemaphore[j]).clear(); } } //status_t AndroidShm::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { // return BnAndroidShm::onTransact(code, data, reply, flags); //} int AndroidShm::allocShm(const int size) { // if negative return value is error ALOGI("try to alloc shared memory size[%d]", size); return MemAlloc(size); } int AndroidShm::removeShm(const unsigned int index) { // shared memory Á¦°Å ALOGI("try to remove shared memory index[%d]", index); if(index >= MAX_SHARED_MEMORY_COUNT) { ALOGE("remove shared memory: out of index"); return -1; } (mMemHeap[index]).clear(); return 1; } int AndroidShm::isAllocated(const unsigned int index) { // allocated ¿©ºÎ È®ÀÎ ALOGI("try to check the memory allocation index[%d]", index); if(index >= MAX_SHARED_MEMORY_COUNT) { ALOGE("shared memory: out of index"); return 0; } if(mMemHeap[index] == NULL) return 0; else return 1; } int AndroidShm::setRegistryIndex(const unsigned int index) { ALOGI("set registry index %d", index); mRegistryIndex = index; return 1; } int AndroidShm::getRegistryIndex() { return mRegistryIndex; } sp AndroidShm::InitSemaphore(const char* name) { ALOGI("init semaphore [%s]", name); for(int i = 0; i < MAX_SEMAPHORE_MEMORY_COUNT; i++) { if(mSemaphoreName[i][0] == SEMAPHORE_NULL_CHAR) { mSemaphore[i] = new MemoryHeapBase(sizeof(sem_t)); if(mSemaphore[i] == NULL){ ALOGI("fail to alloc, try one more..."); continue; } if(sem_init((sem_t*)(mSemaphore[i]->getBase()), 1, 0) == 0) { strncpy(mSemaphoreName[i], name, MAX_SEMAPHORE_NAME_LENGTH - 1); mSemaphoreName[i][MAX_SEMAPHORE_NAME_LENGTH - 1] = '\0'; ALOGI("sem_init success"); return mSemaphore[i]; } else { (mSemaphore[i]).clear(); ALOGE("sem_init failed null returned"); return NULL; } } else { // find already exist name if(strcmp(mSemaphoreName[i], name) == 0) { // found ALOGI("found - return alread allocated semaphore"); return mSemaphore[i]; } } } ALOGE("sem_init failed null returned 2"); return NULL; } }; 1.9.12~dfsg/android/IAndroidShm.cpp0000644000000000000000000000023013214314510015620 0ustar rootroot#include "IAndroidShm.h" #include "BpAndroidShm.h" namespace android{ IMPLEMENT_META_INTERFACE(AndroidShm, "com.samsung.android.jam.IAndroidShm"); }; 1.9.12~dfsg/android/IAndroidShm.h0000644000000000000000000000203013214314510015265 0ustar rootroot#ifndef IANDROIDSHM #define IANDROIDSHM #include #include namespace android { enum { HW_GETBUFFER = IBinder::FIRST_CALL_TRANSACTION, HW_MULTIPLY, HW_STARTSERVER, HW_MAKECLIENT, HW_SENDCOMMAND, HW_LOADSO, HW_ALLOC_SHM, HW_REMOVE_SHM, HW_IS_ALLOCATED, HW_SET_REGISTRY_INDEX, HW_GET_REGISTRY_INDEX, HW_INIT_SEMAPHORE }; class IAndroidShm: public IInterface { public: DECLARE_META_INTERFACE(AndroidShm); virtual sp getBuffer(int index) = 0; virtual int sendCommand(const char *command) = 0; virtual int allocShm(const int size) = 0; // if negative return value is error virtual int removeShm(const unsigned int index) = 0; // shared memory Á¦°Å virtual int isAllocated(const unsigned int index) = 0; // allocated ¿©ºÎ È®ÀÎ virtual int setRegistryIndex(const unsigned int index) = 0; virtual int getRegistryIndex() = 0; // for named semaphore simulation virtual sp InitSemaphore(const char* name) = 0; }; }; #endif 1.9.12~dfsg/android/JackSapaProxy.cpp0000644000000000000000000001456713214314510016220 0ustar rootroot/* Copyright (C) 2014 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackSapaProxy.h" #include "JackServerGlobals.h" #include "JackEngineControl.h" #include "JackLockedEngine.h" #include "JackArgParser.h" #include #include // Example) // sapaproxy // .----------. // sapaproxy:__system_capture_1 -->| |--> sapaproxy:capture_1 // sapaproxy:__system_capture_2 -->| |--> sapaproxy:capture_2 // ... | | ... // | | // sapaproxy:playback_1 ---------->| |--> sapaproxy:__system_playback_1 // sapaproxy:playback_2 ---------->| |--> sapaproxy:__system_playback_2 // sapaproxy:playback_3 ---------->| |--> sapaproxy:__system_playback_3 // sapaproxy:playback_4 ---------->| |--> sapaproxy:__system_playback_4 // ... | | ... // '----------' namespace Jack { JackSapaProxy::JackSapaProxy(jack_client_t* client, const JSList* params) :fClient(client) { jack_log("JackSapaProxy::JackSapaProxy"); fCapturePorts = fPlaybackPorts = 0; const JSList* node; const jack_driver_param_t* param; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*)node->data; switch (param->character) { case 'C': fCapturePorts = (param->value.ui > SAPAPROXY_PORT_NUM_FOR_CLIENT)? SAPAPROXY_PORT_NUM_FOR_CLIENT : param->value.ui; break; case 'P': fPlaybackPorts = (param->value.ui > SAPAPROXY_PORT_NUM_FOR_CLIENT)? SAPAPROXY_PORT_NUM_FOR_CLIENT : param->value.ui; break; } } } JackSapaProxy::~JackSapaProxy() { jack_log("JackSapaProxy::~JackSapaProxy"); } int JackSapaProxy::Setup(jack_client_t* client) { jack_log("JackSapaProxy::Setup"); //refer to system ports and create sapaproxy ports unsigned int i = 0, j = 0; const char **ports_system_capture; const char **ports_system_playback; unsigned int ports_system_capture_cnt = 0; unsigned int ports_system_playback_cnt = 0; char port_name[JACK_PORT_NAME_SIZE] = {0,}; ports_system_capture = jack_get_ports(client, "system:.*", NULL, JackPortIsPhysical | JackPortIsOutput); if (ports_system_capture != NULL) { for (i = 0; i < fCapturePorts && ports_system_capture[i]; i++) { sprintf(port_name, "__system_capture_%d", i + 1); fInputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); sprintf(port_name, "capture_%d", i + 1); fOutputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); ports_system_capture_cnt++; } jack_free(ports_system_capture); } ports_system_playback = jack_get_ports(client, "system:.*", NULL, JackPortIsPhysical | JackPortIsInput); if (ports_system_playback != NULL) { for (j = 0; j < fPlaybackPorts && ports_system_playback[j]; j++, i++) { sprintf(port_name, "playback_%d", j + 1); fInputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); sprintf(port_name, "__system_playback_%d", j + 1); fOutputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); ports_system_playback_cnt++; } jack_free(ports_system_playback); } //store actual number of system ports fCapturePorts = ports_system_capture_cnt; fPlaybackPorts = ports_system_playback_cnt; jack_set_process_callback(client, Process, this); jack_activate(client); //conenct between sapaproxy and system ports for (unsigned int i = 0; i < ports_system_capture_cnt; i++) { sprintf(port_name, "system:capture_%d", i + 1); jack_connect(client, port_name, jack_port_name(fInputPorts[i])); } for (unsigned int i = 0; i < ports_system_playback_cnt; i++) { sprintf(port_name, "system:playback_%d", i + 1); jack_connect(client, jack_port_name(fOutputPorts[ports_system_capture_cnt + i]), port_name); } return 0; } int JackSapaProxy::Process(jack_nframes_t nframes, void* arg) { JackSapaProxy* sapaproxy = static_cast(arg); jack_default_audio_sample_t *in, *out; //for capture for (unsigned int i = 0; i < sapaproxy->fCapturePorts; i++) { in = (jack_default_audio_sample_t*)jack_port_get_buffer(sapaproxy->fInputPorts[i] , nframes); out = (jack_default_audio_sample_t*)jack_port_get_buffer(sapaproxy->fOutputPorts[i], nframes); // TODO: adjust pcm gain each platform here memcpy(out, in, sizeof(jack_default_audio_sample_t) * nframes); } //for playback for (unsigned int i = sapaproxy->fCapturePorts; i < (sapaproxy->fCapturePorts + sapaproxy->fPlaybackPorts); i++) { in = (jack_default_audio_sample_t*)jack_port_get_buffer(sapaproxy->fInputPorts[i] , nframes); out = (jack_default_audio_sample_t*)jack_port_get_buffer(sapaproxy->fOutputPorts[i], nframes); // TODO: adjust pcm gain each platform here memcpy(out, in, sizeof(jack_default_audio_sample_t) * nframes); } return 0; } } // namespace Jack 1.9.12~dfsg/android/JackGoldfishDriver.h0000644000000000000000000000353513214314510016643 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackGoldfishDriver__ #define __JackGoldfishDriver__ #include "JackAudioDriver.h" namespace Jack { /*! \brief The goldfish driver. */ class JackGoldfishDriver : public JackAudioDriver { public: JackGoldfishDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), mFd(-1), mBuffer(NULL) {} virtual ~JackGoldfishDriver() {} int Open(jack_nframes_t buffe_size, jack_nframes_t samplerate, bool capturing, bool playing, int chan_in, int chan_out, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); int Close(); int Read(); int Write(); int SetBufferSize(jack_nframes_t buffer_size); private: int mFd; short *mBuffer; }; } // end of namespace #endif 1.9.12~dfsg/android/JackSapaProxyOut.cpp0000644000000000000000000000600213214314510016671 0ustar rootroot/* Copyright (C) 2014 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackSapaProxy.h" #include "JackServerGlobals.h" #include "JackEngineControl.h" #include "JackLockedEngine.h" #include "JackArgParser.h" #include #include #ifdef __cplusplus extern "C" { #endif #include "driver_interface.h" using namespace Jack; static Jack::JackSapaProxy* sapaproxy = NULL; SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("out", JackDriverNone, "sapaproxy client", &filler); value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamUInt, &value, NULL, "Number of capture ports", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamUInt, &value, NULL, "Number of playback ports", NULL); return desc; } SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params) { if (sapaproxy) { jack_info("sapaproxy already loaded"); return 1; } jack_log("Loading sapaproxy"); sapaproxy = new Jack::JackSapaProxy(jack_client, params); if (!params) { sapaproxy->fCapturePorts = 0U; sapaproxy->fPlaybackPorts = 2U; } sapaproxy->Setup(jack_client); assert(sapaproxy); return 0; } SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init) { JSList* params = NULL; bool parse_params = true; int res = 1; jack_driver_desc_t* desc = jack_get_descriptor(); Jack::JackArgParser parser(load_init); if (parser.GetArgc() > 0) parse_params = parser.ParseParams(desc, ¶ms); if (parse_params) { res = jack_internal_initialize(jack_client, params); parser.FreeParams(params); } return res; } SERVER_EXPORT void jack_finish(void* arg) { Jack::JackSapaProxy* sapaproxy = static_cast(arg); if (sapaproxy) { jack_log("Unloading sapaproxy"); delete sapaproxy; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/android/JackOpenSLESDriver.h0000644000000000000000000000356413214314510016476 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2013 Samsung Electronics This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackOpenSLESDriver__ #define __JackOpenSLESDriver__ #include "JackAudioDriver.h" namespace Jack { /*! \brief The OpenSLES driver. */ class JackOpenSLESDriver : public JackAudioDriver { public: JackOpenSLESDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), inbuffer(NULL), outbuffer(NULL) {} virtual ~JackOpenSLESDriver() {} int Open(jack_nframes_t buffe_size, jack_nframes_t samplerate, bool capturing, bool playing, int chan_in, int chan_out, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); int Close(); int Read(); int Write(); int SetBufferSize(jack_nframes_t buffer_size); private: float *inbuffer; float *outbuffer; }; } // end of namespace #endif 1.9.12~dfsg/android/opensl_io.c0000644000000000000000000003737513214314510015132 0ustar rootroot/* opensl_io.c: Android OpenSL input/output module Copyright (c) 2012, Victor Lazzarini All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "opensl_io.h" //#define CONV16BIT 32768 //#define CONVMYFLT (1./32768.) #define CONV16BIT 32640 #define CONVMYFLT (1./32640.) static void* createThreadLock(void); static int waitThreadLock(void *lock); static void notifyThreadLock(void *lock); static void destroyThreadLock(void *lock); static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context); static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context); // creates the OpenSL ES audio engine static SLresult openSLCreateEngine(OPENSL_STREAM *p) { SLresult result; // create engine result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); if(result != SL_RESULT_SUCCESS) goto engine_end; // realize the engine result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); if(result != SL_RESULT_SUCCESS) goto engine_end; // get the engine interface, which is needed in order to create other objects result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine)); if(result != SL_RESULT_SUCCESS) goto engine_end; engine_end: return result; } // opens the OpenSL ES device for output static SLresult openSLPlayOpen(OPENSL_STREAM *p) { SLresult result; SLuint32 sr = p->sr; SLuint32 channels = p->outchannels; if(channels){ // configure audio source SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; switch(sr){ case 8000: sr = SL_SAMPLINGRATE_8; break; case 11025: sr = SL_SAMPLINGRATE_11_025; break; case 16000: sr = SL_SAMPLINGRATE_16; break; case 22050: sr = SL_SAMPLINGRATE_22_05; break; case 24000: sr = SL_SAMPLINGRATE_24; break; case 32000: sr = SL_SAMPLINGRATE_32; break; case 44100: sr = SL_SAMPLINGRATE_44_1; break; case 48000: sr = SL_SAMPLINGRATE_48; break; case 64000: sr = SL_SAMPLINGRATE_64; break; case 88200: sr = SL_SAMPLINGRATE_88_2; break; case 96000: sr = SL_SAMPLINGRATE_96; break; case 192000: sr = SL_SAMPLINGRATE_192; break; default: return -1; } const SLInterfaceID ids[] = {SL_IID_VOLUME}; const SLboolean req[] = {SL_BOOLEAN_FALSE}; result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req); if(result != SL_RESULT_SUCCESS) goto end_openaudio; // realize the output mix result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE); int speakers; if(channels > 1) speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; else speakers = SL_SPEAKER_FRONT_CENTER; SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,channels, sr, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, speakers, SL_BYTEORDER_LITTLEENDIAN}; SLDataSource audioSrc = {&loc_bufq, &format_pcm}; // configure audio sink SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject}; SLDataSink audioSnk = {&loc_outmix, NULL}; // create audio player const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; const SLboolean req1[] = {SL_BOOLEAN_TRUE}; result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine, &(p->bqPlayerObject), &audioSrc, &audioSnk, 1, ids1, req1); if(result != SL_RESULT_SUCCESS) goto end_openaudio; // realize the player result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE); if(result != SL_RESULT_SUCCESS) goto end_openaudio; // get the play interface result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay)); if(result != SL_RESULT_SUCCESS) goto end_openaudio; // get the buffer queue interface result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(p->bqPlayerBufferQueue)); if(result != SL_RESULT_SUCCESS) goto end_openaudio; // register callback on the buffer queue result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p); if(result != SL_RESULT_SUCCESS) goto end_openaudio; // set the player's state to playing result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING); end_openaudio: return result; } return SL_RESULT_SUCCESS; } // Open the OpenSL ES device for input static SLresult openSLRecOpen(OPENSL_STREAM *p){ SLresult result; SLuint32 sr = p->sr; SLuint32 channels = p->inchannels; if(channels){ switch(sr){ case 8000: sr = SL_SAMPLINGRATE_8; break; case 11025: sr = SL_SAMPLINGRATE_11_025; break; case 16000: sr = SL_SAMPLINGRATE_16; break; case 22050: sr = SL_SAMPLINGRATE_22_05; break; case 24000: sr = SL_SAMPLINGRATE_24; break; case 32000: sr = SL_SAMPLINGRATE_32; break; case 44100: sr = SL_SAMPLINGRATE_44_1; break; case 48000: sr = SL_SAMPLINGRATE_48; break; case 64000: sr = SL_SAMPLINGRATE_64; break; case 88200: sr = SL_SAMPLINGRATE_88_2; break; case 96000: sr = SL_SAMPLINGRATE_96; break; case 192000: sr = SL_SAMPLINGRATE_192; break; default: return -1; } // configure audio source SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; SLDataSource audioSrc = {&loc_dev, NULL}; // configure audio sink int speakers; if(channels > 1) speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; else speakers = SL_SPEAKER_FRONT_CENTER; SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channels, sr, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, speakers, SL_BYTEORDER_LITTLEENDIAN}; SLDataSink audioSnk = {&loc_bq, &format_pcm}; // create audio recorder // (requires the RECORD_AUDIO permission) const SLInterfaceID id[1] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; const SLboolean req[1] = {SL_BOOLEAN_TRUE}; result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine, &(p->recorderObject), &audioSrc, &audioSnk, 1, id, req); if (SL_RESULT_SUCCESS != result) goto end_recopen; // realize the audio recorder result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) goto end_recopen; // get the record interface result = (*p->recorderObject)->GetInterface(p->recorderObject, SL_IID_RECORD, &(p->recorderRecord)); if (SL_RESULT_SUCCESS != result) goto end_recopen; // get the buffer queue interface result = (*p->recorderObject)->GetInterface(p->recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(p->recorderBufferQueue)); if (SL_RESULT_SUCCESS != result) goto end_recopen; // register callback on the buffer queue result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue, bqRecorderCallback, p); if (SL_RESULT_SUCCESS != result) goto end_recopen; result = (*p->recorderRecord)->SetRecordState(p->recorderRecord, SL_RECORDSTATE_RECORDING); end_recopen: return result; } else return SL_RESULT_SUCCESS; } // close the OpenSL IO and destroy the audio engine static void openSLDestroyEngine(OPENSL_STREAM *p){ // destroy buffer queue audio player object, and invalidate all associated interfaces if (p->bqPlayerObject != NULL) { (*p->bqPlayerObject)->Destroy(p->bqPlayerObject); p->bqPlayerObject = NULL; p->bqPlayerPlay = NULL; p->bqPlayerBufferQueue = NULL; p->bqPlayerEffectSend = NULL; } // destroy audio recorder object, and invalidate all associated interfaces if (p->recorderObject != NULL) { (*p->recorderObject)->Destroy(p->recorderObject); p->recorderObject = NULL; p->recorderRecord = NULL; p->recorderBufferQueue = NULL; } // destroy output mix object, and invalidate all associated interfaces if (p->outputMixObject != NULL) { (*p->outputMixObject)->Destroy(p->outputMixObject); p->outputMixObject = NULL; } // destroy engine object, and invalidate all associated interfaces if (p->engineObject != NULL) { (*p->engineObject)->Destroy(p->engineObject); p->engineObject = NULL; p->engineEngine = NULL; } } // open the android audio device for input and/or output OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, int bufferframes){ OPENSL_STREAM *p; p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM),1); p->inchannels = inchannels; p->outchannels = outchannels; p->sr = sr; p->inlock = createThreadLock(); p->outlock = createThreadLock(); if((p->outBufSamples = bufferframes*outchannels) != 0) { if((p->outputBuffer[0] = (short *) calloc(p->outBufSamples, sizeof(short))) == NULL || (p->outputBuffer[1] = (short *) calloc(p->outBufSamples, sizeof(short))) == NULL) { android_CloseAudioDevice(p); return NULL; } } if((p->inBufSamples = bufferframes*inchannels) != 0){ if((p->inputBuffer[0] = (short *) calloc(p->inBufSamples, sizeof(short))) == NULL || (p->inputBuffer[1] = (short *) calloc(p->inBufSamples, sizeof(short))) == NULL){ android_CloseAudioDevice(p); return NULL; } } p->currentInputIndex = 0; p->currentOutputBuffer = 0; p->currentInputIndex = p->inBufSamples; p->currentInputBuffer = 0; if(openSLCreateEngine(p) != SL_RESULT_SUCCESS) { android_CloseAudioDevice(p); return NULL; } if(openSLRecOpen(p) != SL_RESULT_SUCCESS) { android_CloseAudioDevice(p); return NULL; } if(openSLPlayOpen(p) != SL_RESULT_SUCCESS) { android_CloseAudioDevice(p); return NULL; } notifyThreadLock(p->outlock); notifyThreadLock(p->inlock); p->time = 0.; return p; } // close the android audio device void android_CloseAudioDevice(OPENSL_STREAM *p){ if (p == NULL) return; openSLDestroyEngine(p); if (p->inlock != NULL) { notifyThreadLock(p->inlock); destroyThreadLock(p->inlock); p->inlock = NULL; } if (p->outlock != NULL) { notifyThreadLock(p->outlock); destroyThreadLock(p->outlock); p->inlock = NULL; } if (p->outputBuffer[0] != NULL) { free(p->outputBuffer[0]); p->outputBuffer[0] = NULL; } if (p->outputBuffer[1] != NULL) { free(p->outputBuffer[1]); p->outputBuffer[1] = NULL; } if (p->inputBuffer[0] != NULL) { free(p->inputBuffer[0]); p->inputBuffer[0] = NULL; } if (p->inputBuffer[1] != NULL) { free(p->inputBuffer[1]); p->inputBuffer[1] = NULL; } free(p); } // returns timestamp of the processed stream double android_GetTimestamp(OPENSL_STREAM *p){ return p->time; } // this callback handler is called every time a buffer finishes recording void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { OPENSL_STREAM *p = (OPENSL_STREAM *) context; notifyThreadLock(p->inlock); } // gets a buffer of size samples from the device int android_AudioIn(OPENSL_STREAM *p,float *buffer,int size){ short *inBuffer; int i, bufsamps, index; if(p == NULL) return 0; bufsamps = p->inBufSamples; if(bufsamps == 0) return 0; index = p->currentInputIndex; inBuffer = p->inputBuffer[p->currentInputBuffer]; for(i=0; i < size; i++){ if (index >= bufsamps) { waitThreadLock(p->inlock); (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, inBuffer,bufsamps*sizeof(short)); p->currentInputBuffer = (p->currentInputBuffer ? 0 : 1); index = 0; inBuffer = p->inputBuffer[p->currentInputBuffer]; } buffer[i] = (float) inBuffer[index++]*CONVMYFLT; } p->currentInputIndex = index; if(p->outchannels == 0) p->time += (double) size/(p->sr*p->inchannels); return i; } // this callback handler is called every time a buffer finishes playing void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { OPENSL_STREAM *p = (OPENSL_STREAM *) context; notifyThreadLock(p->outlock); } // puts a buffer of size samples to the device int android_AudioOut(OPENSL_STREAM *p, float *buffer,int size){ short *outBuffer; int i, bufsamps, index; if(p == NULL) return 0; bufsamps = p->outBufSamples; if(bufsamps == 0) return 0; index = p->currentOutputIndex; outBuffer = p->outputBuffer[p->currentOutputBuffer]; for(i=0; i < size; i++){ outBuffer[index++] = (short) (buffer[i]*CONV16BIT); if (index >= p->outBufSamples) { waitThreadLock(p->outlock); (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, outBuffer,bufsamps*sizeof(short)); p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1); index = 0; outBuffer = p->outputBuffer[p->currentOutputBuffer]; } } p->currentOutputIndex = index; p->time += (double) size/(p->sr*p->outchannels); return i; } //---------------------------------------------------------------------- // thread Locks // to ensure synchronisation between callbacks and processing code void* createThreadLock(void) { threadLock *p; p = (threadLock*) malloc(sizeof(threadLock)); if (p == NULL) return NULL; memset(p, 0, sizeof(threadLock)); if (pthread_mutex_init(&(p->m), (pthread_mutexattr_t*) NULL) != 0) { free((void*) p); return NULL; } if (pthread_cond_init(&(p->c), (pthread_condattr_t*) NULL) != 0) { pthread_mutex_destroy(&(p->m)); free((void*) p); return NULL; } p->s = (unsigned char) 1; return p; } int waitThreadLock(void *lock) { threadLock *p; int retval = 0; p = (threadLock*) lock; pthread_mutex_lock(&(p->m)); while (!p->s) { pthread_cond_wait(&(p->c), &(p->m)); } p->s = (unsigned char) 0; pthread_mutex_unlock(&(p->m)); return NULL; } void notifyThreadLock(void *lock) { threadLock *p; p = (threadLock*) lock; pthread_mutex_lock(&(p->m)); p->s = (unsigned char) 1; pthread_cond_signal(&(p->c)); pthread_mutex_unlock(&(p->m)); return; } void destroyThreadLock(void *lock) { threadLock *p; p = (threadLock*) lock; if (p == NULL) return; notifyThreadLock(p); pthread_cond_destroy(&(p->c)); pthread_mutex_destroy(&(p->m)); free(p); } 1.9.12~dfsg/posix/0000755000000000000000000000000013214314510012502 5ustar rootroot1.9.12~dfsg/posix/JackFifo.h0000644000000000000000000000337613214314510014340 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackFifo__ #define __JackFifo__ #include "JackSynchro.h" #include "JackCompilerDeps.h" #include #include namespace Jack { /*! \brief Inter process synchronization using Fifo. */ class SERVER_EXPORT JackFifo : public detail::JackSynchro { private: int fFifo; pollfd fPoll; bool ConnectAux(const char* name, const char* server_name, int access); protected: void BuildName(const char* name, const char* server_name, char* res); public: JackFifo():JackSynchro(), fFifo(-1) {} bool Signal(); bool SignalAll(); bool Wait(); bool TimedWait(long usec); bool Allocate(const char* name, const char* server_name, int value); bool Connect(const char* name, const char* server_name); bool ConnectInput(const char* name, const char* server_name); bool ConnectOutput(const char* name, const char* server_name); bool Disconnect(); void Destroy(); }; } // end of namespace #endif 1.9.12~dfsg/posix/JackSocketNotifyChannel.h0000644000000000000000000000265713214314510017370 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSocketNotifyChannel__ #define __JackSocketNotifyChannel__ #include "JackChannel.h" #include "JackSocket.h" namespace Jack { /*! \brief JackNotifyChannel using sockets. */ class JackSocketNotifyChannel { private: JackClientSocket fNotifySocket; // Socket to communicate with the server : from server to client public: JackSocketNotifyChannel() {} int Open(const char* name); // Open the Server/Client connection void Close(); // Close the Server/Client connection void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); }; } // end of namespace #endif 1.9.12~dfsg/posix/JackSocketNotifyChannel.cpp0000644000000000000000000000424513214314510017716 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackRequest.h" #include "JackSocketNotifyChannel.h" #include "JackError.h" #include "JackConstants.h" namespace Jack { // Server to client int JackSocketNotifyChannel::Open(const char* name) { jack_log("JackSocketNotifyChannel::Open name = %s", name); // Connect to client listen socket if (fNotifySocket.Connect(jack_client_dir, name, 0) < 0) { jack_error("Cannot connect client socket"); return -1; } // Use a time out for notifications fNotifySocket.SetReadTimeOut(SOCKET_TIME_OUT); return 0; } void JackSocketNotifyChannel::Close() { jack_log("JackSocketNotifyChannel::Close"); fNotifySocket.Close(); } void JackSocketNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) { JackClientNotification event(name, refnum, notify, sync, message, value1, value2); JackResult res; // Send notification if (event.Write(&fNotifySocket) < 0) { jack_error("Could not write notification"); *result = -1; return; } // Read the result in "synchronous" mode only if (sync) { // Get result : use a time out if (res.Read(&fNotifySocket) < 0) { jack_error("Could not read notification result"); *result = -1; } else { *result = res.fResult; } } else { *result = 0; } } } // end of namespace 1.9.12~dfsg/posix/JackShmMem_os.h0000644000000000000000000000206613214314510015337 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackShmMem_POSIX__ #define __JackShmMem_POSIX__ #include #include #define CHECK_MLOCK(ptr, size) (mlock((ptr), (size)) == 0) #define CHECK_MUNLOCK(ptr, size) (munlock((ptr), (size)) == 0) #define CHECK_MLOCKALL() (mlockall(MCL_CURRENT | MCL_FUTURE) == 0) #define CHECK_MUNLOCKALL() (munlockall() == 0) #endif 1.9.12~dfsg/posix/JackPosixSemaphore.cpp0000644000000000000000000001566113214314510016756 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackPosixSemaphore.h" #include "JackTools.h" #include "JackConstants.h" #include "JackError.h" #include #include #include #ifdef __linux__ #include "promiscuous.h" #endif namespace Jack { JackPosixSemaphore::JackPosixSemaphore() : JackSynchro(), fSemaphore(NULL) { const char* promiscuous = getenv("JACK_PROMISCUOUS_SERVER"); fPromiscuous = (promiscuous != NULL); #ifdef __linux__ fPromiscuousGid = jack_group2gid(promiscuous); #endif } void JackPosixSemaphore::BuildName(const char* client_name, const char* server_name, char* res, int size) { char ext_client_name[SYNC_MAX_NAME_SIZE + 1]; JackTools::RewriteName(client_name, ext_client_name); #if __APPLE__ // POSIX semaphore names are limited to 32 characters... snprintf(res, 32, "js_%s", ext_client_name); #else if (fPromiscuous) { snprintf(res, size, "jack_sem.%s_%s", server_name, ext_client_name); } else { snprintf(res, size, "jack_sem.%d_%s_%s", JackTools::GetUID(), server_name, ext_client_name); } #endif } bool JackPosixSemaphore::Signal() { int res; if (!fSemaphore) { jack_error("JackPosixSemaphore::Signal name = %s already deallocated!!", fName); return false; } if (fFlush) { return true; } if ((res = sem_post(fSemaphore)) != 0) { jack_error("JackPosixSemaphore::Signal name = %s err = %s", fName, strerror(errno)); } return (res == 0); } bool JackPosixSemaphore::SignalAll() { int res; if (!fSemaphore) { jack_error("JackPosixSemaphore::SignalAll name = %s already deallocated!!", fName); return false; } if (fFlush) { return true; } if ((res = sem_post(fSemaphore)) != 0) { jack_error("JackPosixSemaphore::SignalAll name = %s err = %s", fName, strerror(errno)); } return (res == 0); } bool JackPosixSemaphore::Wait() { int res; if (!fSemaphore) { jack_error("JackPosixSemaphore::Wait name = %s already deallocated!!", fName); return false; } while ((res = sem_wait(fSemaphore) < 0)) { jack_error("JackPosixSemaphore::Wait name = %s err = %s", fName, strerror(errno)); if (errno != EINTR) { break; } } return (res == 0); } #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) // glibc feature test bool JackPosixSemaphore::TimedWait(long usec) { int res; struct timeval now; timespec time; if (!fSemaphore) { jack_error("JackPosixSemaphore::TimedWait name = %s already deallocated!!", fName); return false; } gettimeofday(&now, 0); time.tv_sec = now.tv_sec + usec / 1000000; long tv_usec = (now.tv_usec + (usec % 1000000)); time.tv_sec += tv_usec / 1000000; time.tv_nsec = (tv_usec % 1000000) * 1000; while ((res = sem_timedwait(fSemaphore, &time)) < 0) { jack_error("JackPosixSemaphore::TimedWait err = %s", strerror(errno)); jack_log("JackPosixSemaphore::TimedWait now : %ld %ld ", now.tv_sec, now.tv_usec); jack_log("JackPosixSemaphore::TimedWait next : %ld %ld ", time.tv_sec, time.tv_nsec/1000); if (errno != EINTR) { break; } } return (res == 0); } #else #warning "JackPosixSemaphore::TimedWait is not supported: Jack in SYNC mode with JackPosixSemaphore will not run properly !!" bool JackPosixSemaphore::TimedWait(long usec) { return Wait(); } #endif // Server side : publish the semaphore in the global namespace bool JackPosixSemaphore::Allocate(const char* name, const char* server_name, int value) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackPosixSemaphore::Allocate name = %s val = %ld", fName, value); if ((fSemaphore = sem_open(fName, O_CREAT | O_RDWR, 0777, value)) == (sem_t*)SEM_FAILED) { jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno)); return false; } else { #ifdef __linux__ if (fPromiscuous) { char sempath[SYNC_MAX_NAME_SIZE+13]; snprintf(sempath, sizeof(sempath), "/dev/shm/sem.%s", fName); if (jack_promiscuous_perms(-1, sempath, fPromiscuousGid) < 0) return false; } #endif return true; } } // Client side : get the published semaphore from server bool JackPosixSemaphore::ConnectInput(const char* name, const char* server_name) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackPosixSemaphore::Connect name = %s", fName); // Temporary... if (fSemaphore) { jack_log("Already connected name = %s", name); return true; } if ((fSemaphore = sem_open(fName, O_RDWR)) == (sem_t*)SEM_FAILED) { jack_error("Connect: can't connect named semaphore name = %s err = %s", fName, strerror(errno)); return false; } else if (fSemaphore) { int val = 0; sem_getvalue(fSemaphore, &val); jack_log("JackPosixSemaphore::Connect sem_getvalue %ld", val); return true; } else { jack_error("Connect: fSemaphore not initialized!"); return false; } } bool JackPosixSemaphore::Connect(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackPosixSemaphore::ConnectOutput(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackPosixSemaphore::Disconnect() { if (fSemaphore) { jack_log("JackPosixSemaphore::Disconnect name = %s", fName); if (sem_close(fSemaphore) != 0) { jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno)); return false; } else { fSemaphore = NULL; return true; } } else { return true; } } // Server side : destroy the semaphore void JackPosixSemaphore::Destroy() { if (fSemaphore != NULL) { jack_log("JackPosixSemaphore::Destroy name = %s", fName); sem_unlink(fName); if (sem_close(fSemaphore) != 0) { jack_error("Destroy: can't destroy semaphore name = %s err = %s", fName, strerror(errno)); } fSemaphore = NULL; } else { jack_error("JackPosixSemaphore::Destroy semaphore == NULL"); } } } // end of namespace 1.9.12~dfsg/posix/JackSystemDeps_os.h0000644000000000000000000000263313214314510016251 0ustar rootroot/* Copyright (C) 2004-2006 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackSystemDeps_POSIX__ #define __JackSystemDeps_POSIX__ #include #include #include #include #ifndef UINT32_MAX #define UINT32_MAX 4294967295U #endif #define DRIVER_HANDLE void* #define LoadDriverModule(name) dlopen((name), RTLD_NOW | RTLD_GLOBAL) #define UnloadDriverModule(handle) dlclose((handle)) #define GetDriverProc(handle, name) dlsym((handle), (name)) #define JACK_HANDLE void* #define LoadJackModule(name) dlopen((name), RTLD_NOW | RTLD_LOCAL); #define UnloadJackModule(handle) dlclose((handle)); #define GetJackProc(handle, name) dlsym((handle), (name)); #define JACK_DEBUG (getenv("JACK_CLIENT_DEBUG") && strcmp(getenv("JACK_CLIENT_DEBUG"), "on") == 0) #endif 1.9.12~dfsg/posix/JackPosixServerLaunch.cpp0000644000000000000000000001746013214314510017433 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(WIN32) || defined(__CYGWIN__) #ifdef PTHREAD_WIN32 // Added by JE - 13-02-2010 #include // Makes sure we #include the ptw32 version for #endif // consistency - even though we won't need it ! #include "JackConstants.h" #include "JackChannel.h" #include "JackLibGlobals.h" #include "JackServerLaunch.h" #include "JackPlatformPlug.h" #include using namespace Jack; #if defined(USE_LIBDBUS_AUTOLAUNCH) #include static int start_server_dbus(const char* server_name) { DBusError err; DBusConnection *conn; DBusMessage *msg; // initialise the errors dbus_error_init(&err); // connect to the bus conn = dbus_bus_get(DBUS_BUS_SESSION, &err); if (dbus_error_is_set(&err)) { fprintf(stderr, "Connection Error (%s)\n", err.message); dbus_error_free(&err); } if (NULL == conn) { return 1; } msg = dbus_message_new_method_call( "org.jackaudio.service", // target for the method call "/org/jackaudio/Controller", // object to call on "org.jackaudio.JackControl", // interface to call on "StartServer"); // method name if (NULL == msg) { fprintf(stderr, "Message Null\n"); return 1; } // send message and get a handle for a reply if (!dbus_connection_send(conn, msg, NULL)) { fprintf(stderr, "Out Of Memory!\n"); return 1; } dbus_message_unref(msg); dbus_connection_flush(conn); dbus_error_free(&err); return 0; } #elif defined(USE_CLASSIC_AUTOLAUNCH) /* Exec the JACK server in this process. Does not return. */ static void start_server_classic_aux(const char* server_name) { FILE* fp = 0; char filename[255]; char arguments[255]; char buffer[255]; char* command = 0; size_t pos = 0; size_t result = 0; char** argv = 0; int i = 0; int good = 0; int res; snprintf(filename, 255, "%s/.jackdrc", getenv("HOME")); fp = fopen(filename, "r"); if (!fp) { fp = fopen("/etc/jackdrc", "r"); } /* if still not found, check old config name for backwards compatability */ if (!fp) { fp = fopen("/etc/jackd.conf", "r"); } if (fp) { arguments[0] = '\0'; res = fscanf(fp, "%s", buffer); while (res != 0 && res != EOF) { strcat(arguments, buffer); strcat(arguments, " "); res = fscanf(fp, "%s", buffer); } if (strlen(arguments) > 0) { good = 1; } fclose(fp); } if (!good) { command = (char*)(JACK_LOCATION "/jackd"); strncpy(arguments, JACK_LOCATION "/jackd -T -d " JACK_DEFAULT_DRIVER, 255); } else { result = strcspn(arguments, " "); command = (char*)malloc(result + 1); strncpy(command, arguments, result); command[result] = '\0'; } argv = (char**)malloc(255); while (1) { /* insert -T and -nserver_name in front of arguments */ if (i == 1) { argv[i] = (char*)malloc(strlen ("-T") + 1); strcpy (argv[i++], "-T"); if (server_name) { size_t optlen = strlen("-n"); char* buf = (char*)malloc(optlen + strlen(server_name) + 1); strcpy(buf, "-n"); strcpy(buf + optlen, server_name); argv[i++] = buf; } } /* skip whitespace */ while (pos < strlen(arguments) && arguments[pos] && arguments[pos] == ' ') { ++pos; } if (pos >= strlen(arguments)) { break; } if (arguments[pos] == '\"') { ++pos; result = strcspn(arguments + pos, "\""); } else { result = strcspn(arguments + pos, " "); } if (0 == result) { break; } argv[i] = (char*)malloc(result + 1); strncpy(argv[i], arguments + pos, result); argv[i][result] = '\0'; pos += result + 1; if (++i > 253) { break; } } argv[i] = 0; execv(command, argv); /* If execv() succeeds, it does not return. There's no point * in calling jack_error() here in the child process. */ fprintf(stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror(errno)); } static int start_server_classic(const char* server_name) { /* The double fork() forces the server to become a child of * init, which will always clean up zombie process state on * termination. This even works in cases where the server * terminates but this client does not. * * Since fork() is usually implemented using copy-on-write * virtual memory tricks, the overhead of the second fork() is * probably relatively small. */ int status; pid_t first_child_pid; first_child_pid = fork(); switch (first_child_pid) { case 0: /* child process */ switch (fork()) { case 0: /* grandchild process */ start_server_classic_aux(server_name); _exit(99); /* exec failed */ case - 1: _exit(98); default: _exit(0); } case - 1: /* fork() error */ return 1; /* failed to start server */ } waitpid(first_child_pid, &status, 0); /* only the original parent process goes here */ return 0; /* (probably) successful */ } #endif static int start_server(const char* server_name, jack_options_t options) { if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) { return 1; } #if defined(USE_LIBDBUS_AUTOLAUNCH) return start_server_dbus(server_name); #elif defined(USE_CLASSIC_AUTOLAUNCH) return start_server_classic(server_name); #else fprintf(stderr, "Automatic start of JACK server is disabled at configure time\n"); return 1; #endif } static int server_connect(char* server_name) { JackClientChannel channel; int res = channel.ServerCheck(server_name); channel.Close(); JackSleep(2000); // Added by JE - 02-01-2009 (gives // the channel some time to close) return res; } int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status) { if (server_connect(va->server_name) < 0) { int trys; if (start_server(va->server_name, options)) { int my_status1 = *status | JackFailure | JackServerFailed; *status = (jack_status_t)my_status1; return -1; } trys = 5; do { sleep(1); if (--trys < 0) { int my_status1 = *status | JackFailure | JackServerFailed; *status = (jack_status_t)my_status1; return -1; } } while (server_connect(va->server_name) < 0); int my_status1 = *status | JackServerStarted; *status = (jack_status_t)my_status1; } return 0; } #endif // !defined(WIN32) || defined(__CYGWIN__) 1.9.12~dfsg/posix/JackPosixMutex.cpp0000644000000000000000000000746213214314510016135 0ustar rootroot/* Copyright (C) 2006 Grame This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France grame@grame.fr */ #include "JackPosixMutex.h" #include "JackError.h" namespace Jack { JackBasePosixMutex::JackBasePosixMutex(const char* name) :fOwner(0) { int res = pthread_mutex_init(&fMutex, NULL); ThrowIf(res != 0, JackException("JackBasePosixMutex: could not init the mutex")); } JackBasePosixMutex::~JackBasePosixMutex() { pthread_mutex_destroy(&fMutex); } bool JackBasePosixMutex::Lock() { pthread_t current_thread = pthread_self(); if (!pthread_equal(current_thread, fOwner)) { int res = pthread_mutex_lock(&fMutex); if (res == 0) { fOwner = current_thread; return true; } else { jack_error("JackBasePosixMutex::Lock res = %d", res); return false; } } else { return false; } } bool JackBasePosixMutex::Trylock() { pthread_t current_thread = pthread_self(); if (!pthread_equal(current_thread, fOwner)) { int res = pthread_mutex_trylock(&fMutex); if (res == 0) { fOwner = current_thread; return true; } else { return false; } } else { return false; } } bool JackBasePosixMutex::Unlock() { if (pthread_equal(pthread_self(), fOwner)) { fOwner = 0; int res = pthread_mutex_unlock(&fMutex); if (res == 0) { return true; } else { jack_error("JackBasePosixMutex::Unlock res = %d", res); return false; } } else { return false; } } JackPosixMutex::JackPosixMutex(const char* name) { // Use recursive mutex pthread_mutexattr_t mutex_attr; int res; res = pthread_mutexattr_init(&mutex_attr); ThrowIf(res != 0, JackException("JackBasePosixMutex: could not init the mutex attribute")); res = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); ThrowIf(res != 0, JackException("JackBasePosixMutex: could not settype the mutex")); res = pthread_mutex_init(&fMutex, &mutex_attr); ThrowIf(res != 0, JackException("JackBasePosixMutex: could not init the mutex")); pthread_mutexattr_destroy(&mutex_attr); } JackPosixMutex::~JackPosixMutex() { pthread_mutex_destroy(&fMutex); } bool JackPosixMutex::Lock() { int res = pthread_mutex_lock(&fMutex); if (res != 0) { jack_log("JackPosixMutex::Lock res = %d", res); } return (res == 0); } bool JackPosixMutex::Trylock() { return (pthread_mutex_trylock(&fMutex) == 0); } bool JackPosixMutex::Unlock() { int res = pthread_mutex_unlock(&fMutex); if (res != 0) { jack_log("JackPosixMutex::Unlock res = %d", res); } return (res == 0); } } // namespace 1.9.12~dfsg/posix/JackPosixThread.h0000644000000000000000000000606713214314510015707 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPosixThread__ #define __JackPosixThread__ #include "JackThread.h" #include namespace Jack { /* use 512KB stack per thread - the default is way too high to be feasible * with mlockall() on many systems */ #define THREAD_STACK 524288 /*! \brief The POSIX thread base class. */ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface { protected: jack_native_thread_t fThread; static void* ThreadHandler(void* arg); public: JackPosixThread(JackRunnableInterface* runnable, bool real_time, int priority, int cancellation) : JackThreadInterface(runnable, priority, real_time, cancellation), fThread((jack_native_thread_t)NULL) {} JackPosixThread(JackRunnableInterface* runnable, int cancellation = PTHREAD_CANCEL_ASYNCHRONOUS) : JackThreadInterface(runnable, 0, false, cancellation), fThread((jack_native_thread_t)NULL) {} int Start(); int StartSync(); int Kill(); int Stop(); void Terminate(); int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself jack_native_thread_t GetThreadID(); bool IsThread(); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) { return JackPosixThread::AcquireRealTimeImp(thread, priority); } static int DropRealTimeImp(jack_native_thread_t thread); static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); static int StopImp(jack_native_thread_t thread); static int KillImp(jack_native_thread_t thread); }; SERVER_EXPORT void ThreadExit(); } // end of namespace #endif 1.9.12~dfsg/posix/JackSocketClientChannel.h0000644000000000000000000000360313214314510017326 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSocketClientChannel__ #define __JackSocketClientChannel__ #include "JackGenericClientChannel.h" #include "JackSocket.h" #include "JackPlatformPlug.h" #include "JackThread.h" namespace Jack { class JackClient; /*! \brief JackClientChannel using sockets. */ class JackSocketClientChannel : public JackGenericClientChannel, public JackRunnableInterface { private: JackServerSocket fNotificationListenSocket; // Socket listener for server notification JackClientSocket* fNotificationSocket; // Socket for server notification JackThread fThread; // Thread to execute the event loop JackClient* fClient; public: JackSocketClientChannel(); virtual ~JackSocketClientChannel(); int Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status); void Close(); int Start(); void Stop(); // JackRunnableInterface interface bool Init(); bool Execute(); bool IsChannelThread() { return fThread.IsThread(); } }; } // end of namespace #endif 1.9.12~dfsg/posix/JackSocketServerChannel.cpp0000644000000000000000000002035313214314510017712 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackSocketServerChannel.h" #include "JackRequest.h" #include "JackServer.h" #include "JackLockedEngine.h" #include "JackGlobals.h" #include "JackServerGlobals.h" #include "JackClient.h" #include "JackTools.h" #include "JackNotification.h" #include "JackException.h" #include #include using namespace std; namespace Jack { JackSocketServerChannel::JackSocketServerChannel(): fThread(this), fDecoder(NULL) { fPollTable = NULL; fRebuild = true; } JackSocketServerChannel::~JackSocketServerChannel() { delete[] fPollTable; } int JackSocketServerChannel::Open(const char* server_name, JackServer* server) { jack_log("JackSocketServerChannel::Open"); // Prepare request socket if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) { jack_log("JackSocketServerChannel::Open : cannot create result listen socket"); return -1; } // Prepare for poll BuildPoolTable(); fDecoder = new JackRequestDecoder(server, this); fServer = server; return 0; } void JackSocketServerChannel::Close() { fRequestListenSocket.Close(); // Close remaining client sockets std::map >::iterator it; for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) { pair elem = (*it).second; JackClientSocket* socket = elem.second; assert(socket); socket->Close(); delete socket; } delete fDecoder; fDecoder = NULL; } int JackSocketServerChannel::Start() { if (fThread.Start() != 0) { jack_error("Cannot start Jack server listener"); return -1; } else { return 0; } } void JackSocketServerChannel::Stop() { fThread.Stop(); } void JackSocketServerChannel::ClientCreate() { jack_log("JackSocketServerChannel::ClientCreate socket"); JackClientSocket* socket = fRequestListenSocket.Accept(); if (socket) { fSocketTable[socket->GetFd()] = make_pair(-1, socket); fRebuild = true; } else { jack_error("Client socket cannot be created"); } } int JackSocketServerChannel::GetFd(JackClientSocket* socket_aux) { std::map >::iterator it; for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) { pair elem = (*it).second; JackClientSocket* socket = elem.second; if (socket_aux == socket) { return (*it).first; } } return -1; } void JackSocketServerChannel::ClientAdd(detail::JackChannelTransactionInterface* socket_aux, JackClientOpenRequest* req, JackClientOpenResult *res) { int refnum = -1; res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &refnum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph); if (res->fResult == 0) { JackClientSocket* socket = dynamic_cast(socket_aux); assert(socket); int fd = GetFd(socket); assert(fd >= 0); fSocketTable[fd].first = refnum; fRebuild = true; jack_log("JackSocketServerChannel::ClientAdd ref = %d fd = %d", refnum, fd); #ifdef __APPLE__ int on = 1; if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) { jack_log("JackSocketServerChannel::ClientAdd : setsockopt SO_NOSIGPIPE fd = %ld err = %s", fd, strerror(errno)); } #endif } else { jack_error("Cannot create new client"); } } void JackSocketServerChannel::ClientRemove(detail::JackChannelTransactionInterface* socket_aux, int refnum) { JackClientSocket* socket = dynamic_cast(socket_aux); assert(socket); int fd = GetFd(socket); assert(fd >= 0); jack_log("JackSocketServerChannel::ClientRemove ref = %d fd = %d", refnum, fd); fSocketTable.erase(fd); socket->Close(); delete socket; fRebuild = true; } void JackSocketServerChannel::ClientKill(int fd) { pair elem = fSocketTable[fd]; JackClientSocket* socket = elem.second; int refnum = elem.first; assert(socket); jack_log("JackSocketServerChannel::ClientKill ref = %d fd = %d", refnum, fd); if (refnum == -1) { // Should never happen... correspond to a client that started the socket but never opened... jack_log("Client was not opened : probably correspond to server_check"); } else { fServer->GetEngine()->ClientKill(refnum); } fSocketTable.erase(fd); socket->Close(); delete socket; fRebuild = true; } void JackSocketServerChannel::BuildPoolTable() { if (fRebuild) { fRebuild = false; delete[] fPollTable; fPollTable = new pollfd[fSocketTable.size() + 1]; jack_log("JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable.size() + 1); // First fd is the server request socket fPollTable[0].fd = fRequestListenSocket.GetFd(); fPollTable[0].events = POLLIN | POLLERR; // Next fd for clients map >::iterator it; int i; for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) { jack_log("JackSocketServerChannel::BuildPoolTable fSocketTable i = %ld fd = %ld", i, it->first); fPollTable[i].fd = it->first; fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; } } } bool JackSocketServerChannel::Init() { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGPIPE); pthread_sigmask(SIG_BLOCK, &set, 0); return true; } bool JackSocketServerChannel::Execute() { try { // Global poll if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) { jack_error("JackSocketServerChannel::Execute : engine poll failed err = %s request thread quits...", strerror(errno)); return false; } else { // Poll all clients for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) { int fd = fPollTable[i].fd; jack_log("JackSocketServerChannel::Execute : fPollTable i = %ld fd = %ld", i, fd); if (fPollTable[i].revents & ~POLLIN) { jack_log("JackSocketServerChannel::Execute : poll client error err = %s", strerror(errno)); ClientKill(fd); } else if (fPollTable[i].revents & POLLIN) { JackClientSocket* socket = fSocketTable[fd].second; // Decode header JackRequest header; if (header.Read(socket) < 0) { jack_log("JackSocketServerChannel::Execute : cannot decode header"); ClientKill(fd); // Decode request } else { // Result is not needed here fDecoder->HandleRequest(socket, header.fType); } } } // Check the server request socket */ if (fPollTable[0].revents & POLLERR) { jack_error("Error on server request socket err = %s", strerror(errno)); } if (fPollTable[0].revents & POLLIN) { ClientCreate(); } } BuildPoolTable(); return true; } catch (JackQuitException& e) { jack_log("JackSocketServerChannel::Execute : JackQuitException"); return false; } } } // end of namespace 1.9.12~dfsg/posix/JackPosixSemaphore.h0000644000000000000000000000343713214314510016421 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPosixSemaphore__ #define __JackPosixSemaphore__ #include "JackSynchro.h" #include "JackCompilerDeps.h" #include #include #include namespace Jack { /*! \brief Inter process synchronization using POSIX semaphore. */ class SERVER_EXPORT JackPosixSemaphore : public detail::JackSynchro { private: sem_t* fSemaphore; bool fPromiscuous; #ifdef __linux__ int fPromiscuousGid; #endif protected: void BuildName(const char* name, const char* server_name, char* res, int size); public: JackPosixSemaphore(); bool Signal(); bool SignalAll(); bool Wait(); bool TimedWait(long usec); bool Allocate(const char* name, const char* server_name, int value); bool Connect(const char* name, const char* server_name); bool ConnectInput(const char* name, const char* server_name); bool ConnectOutput(const char* name, const char* server_name); bool Disconnect(); void Destroy(); }; } // end of namespace #endif 1.9.12~dfsg/posix/JackCompilerDeps_os.h0000644000000000000000000000252513214314510016537 0ustar rootroot/* Copyright (C) 2004-2005 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCompilerDeps_POSIX__ #define __JackCompilerDeps_POSIX__ #include "JackConstants.h" #if __GNUC__ #define MEM_ALIGN(x,y) x __attribute__((aligned(y))) #define LIB_EXPORT __attribute__((visibility("default"))) #ifdef SERVER_SIDE #if (__GNUC__< 4) #define SERVER_EXPORT #else #define SERVER_EXPORT __attribute__((visibility("default"))) #endif #else #define SERVER_EXPORT __attribute__((visibility("hidden"))) #endif #else #define MEM_ALIGN(x,y) x #define LIB_EXPORT #define SERVER_EXPORT /* Add other things here for non-gcc platforms */ #endif #endif 1.9.12~dfsg/posix/JackSocketServerChannel.h0000644000000000000000000000442013214314510017354 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSocketServerChannel__ #define __JackSocketServerChannel__ #include "JackSocket.h" #include "JackPlatformPlug.h" #include "JackRequestDecoder.h" #include #include namespace Jack { class JackServer; /*! \brief JackServerChannel using sockets. */ class JackSocketServerChannel : public JackRunnableInterface, public JackClientHandlerInterface { private: JackServerSocket fRequestListenSocket; // Socket to create request socket for the client JackThread fThread; // Thread to execute the event loop JackRequestDecoder* fDecoder; JackServer* fServer; pollfd* fPollTable; bool fRebuild; std::map > fSocketTable; void BuildPoolTable(); void ClientCreate(); void ClientKill(int fd); void ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult *res); void ClientRemove(detail::JackChannelTransactionInterface* socket, int refnum); int GetFd(JackClientSocket* socket); public: JackSocketServerChannel(); ~JackSocketServerChannel(); int Open(const char* server_name, JackServer* server); // Open the Server/Client connection void Close(); // Close the Server/Client connection int Start(); void Stop(); // JackRunnableInterface interface bool Init(); bool Execute(); }; } // end of namespace #endif 1.9.12~dfsg/posix/JackPosixProcessSync.cpp0000644000000000000000000001266113214314510017303 0ustar rootroot /* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackPosixProcessSync.h" #include "JackError.h" namespace Jack { void JackPosixProcessSync::Signal() { int res = pthread_cond_signal(&fCond); if (res != 0) { jack_error("JackPosixProcessSync::Signal error err = %s", strerror(res)); } } // TO DO : check thread consistency? void JackPosixProcessSync::LockedSignal() { int res = pthread_mutex_lock(&fMutex); if (res != 0) { jack_error("JackPosixProcessSync::LockedSignal error err = %s", strerror(res)); } res = pthread_cond_signal(&fCond); if (res != 0) { jack_error("JackPosixProcessSync::LockedSignal error err = %s", strerror(res)); } res = pthread_mutex_unlock(&fMutex); if (res != 0) { jack_error("JackPosixProcessSync::LockedSignal error err = %s", strerror(res)); } } void JackPosixProcessSync::SignalAll() { int res = pthread_cond_broadcast(&fCond); if (res != 0) { jack_error("JackPosixProcessSync::SignalAll error err = %s", strerror(res)); } } // TO DO : check thread consistency? void JackPosixProcessSync::LockedSignalAll() { int res = pthread_mutex_lock(&fMutex); if (res != 0) { jack_error("JackPosixProcessSync::LockedSignalAll error err = %s", strerror(res)); } res = pthread_cond_broadcast(&fCond); if (res != 0) { jack_error("JackPosixProcessSync::LockedSignalAll error err = %s", strerror(res)); } res = pthread_mutex_unlock(&fMutex); if (res != 0) { jack_error("JackPosixProcessSync::LockedSignalAll error err = %s", strerror(res)); } } void JackPosixProcessSync::Wait() { ThrowIf(!pthread_equal(pthread_self(), fOwner), JackException("JackPosixProcessSync::Wait: a thread has to have locked a mutex before it can wait")); fOwner = 0; int res = pthread_cond_wait(&fCond, &fMutex); if (res != 0) { jack_error("JackPosixProcessSync::Wait error err = %s", strerror(res)); } else { fOwner = pthread_self(); } } // TO DO : check thread consistency? void JackPosixProcessSync::LockedWait() { int res; res = pthread_mutex_lock(&fMutex); if (res != 0) { jack_error("JackPosixProcessSync::LockedWait error err = %s", strerror(res)); } if ((res = pthread_cond_wait(&fCond, &fMutex)) != 0) { jack_error("JackPosixProcessSync::LockedWait error err = %s", strerror(res)); } res = pthread_mutex_unlock(&fMutex); if (res != 0) { jack_error("JackPosixProcessSync::LockedWait error err = %s", strerror(res)); } } bool JackPosixProcessSync::TimedWait(long usec) { ThrowIf(!pthread_equal(pthread_self(), fOwner), JackException("JackPosixProcessSync::TimedWait: a thread has to have locked a mutex before it can wait")); fOwner = 0; struct timeval T0, T1; timespec time; struct timeval now; int res; jack_log("JackPosixProcessSync::TimedWait time out = %ld", usec); gettimeofday(&T0, 0); gettimeofday(&now, 0); unsigned int next_date_usec = now.tv_usec + usec; time.tv_sec = now.tv_sec + (next_date_usec / 1000000); time.tv_nsec = (next_date_usec % 1000000) * 1000; res = pthread_cond_timedwait(&fCond, &fMutex, &time); if (res != 0) { jack_error("JackPosixProcessSync::TimedWait error usec = %ld err = %s", usec, strerror(res)); } else { fOwner = pthread_self(); } gettimeofday(&T1, 0); jack_log("JackPosixProcessSync::TimedWait finished delta = %5.1lf", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); return (res == 0); } // TO DO : check thread consistency? bool JackPosixProcessSync::LockedTimedWait(long usec) { struct timeval T0, T1; timespec time; struct timeval now; int res1, res2; res1 = pthread_mutex_lock(&fMutex); if (res1 != 0) { jack_error("JackPosixProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); } jack_log("JackPosixProcessSync::TimedWait time out = %ld", usec); gettimeofday(&T0, 0); gettimeofday(&now, 0); unsigned int next_date_usec = now.tv_usec + usec; time.tv_sec = now.tv_sec + (next_date_usec / 1000000); time.tv_nsec = (next_date_usec % 1000000) * 1000; res2 = pthread_cond_timedwait(&fCond, &fMutex, &time); if (res2 != 0) { jack_error("JackPosixProcessSync::LockedTimedWait error usec = %ld err = %s", usec, strerror(res2)); } gettimeofday(&T1, 0); res1 = pthread_mutex_unlock(&fMutex); if (res1 != 0) { jack_error("JackPosixProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); } jack_log("JackPosixProcessSync::TimedWait finished delta = %5.1lf", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); return (res2 == 0); } } // end of namespace 1.9.12~dfsg/posix/JackTypes_os.h0000644000000000000000000000203413214314510015250 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackTypes_POSIX__ #define __JackTypes_POSIX__ #include #include typedef unsigned long long UInt64; typedef pthread_key_t jack_tls_key; typedef int (*jack_thread_creator_t)(pthread_t*, const pthread_attr_t*, void* (*function)(void*), void* arg); #endif 1.9.12~dfsg/posix/JackNetUnixSocket.cpp0000644000000000000000000003773013214314510016554 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackNetUnixSocket.h" #include "JackError.h" #include #include using namespace std; namespace Jack { //utility ********************************************************************************************************* int GetHostName(char * name, int size) { if (gethostname(name, size) == SOCKET_ERROR) { jack_error("Can't get 'hostname' : %s", strerror(NET_ERROR_CODE)); strcpy(name, "default"); return SOCKET_ERROR; } return 0; } //construct/destruct*********************************************************************************************** JackNetUnixSocket::JackNetUnixSocket() { fSockfd = 0; fPort = 0; fTimeOut = 0; fSendAddr.sin_family = AF_INET; fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fRecvAddr.sin_zero, 0, 8); } JackNetUnixSocket::JackNetUnixSocket(const char* ip, int port) { fSockfd = 0; fPort = port; fTimeOut = 0; fSendAddr.sin_family = AF_INET; fSendAddr.sin_port = htons(port); inet_aton(ip, &fSendAddr.sin_addr); memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; fRecvAddr.sin_port = htons(port); fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fRecvAddr.sin_zero, 0, 8); } JackNetUnixSocket::JackNetUnixSocket(const JackNetUnixSocket& socket) { fSockfd = 0; fTimeOut = 0; fPort = socket.fPort; fSendAddr = socket.fSendAddr; fRecvAddr = socket.fRecvAddr; } JackNetUnixSocket::~JackNetUnixSocket() { Close(); } JackNetUnixSocket& JackNetUnixSocket::operator=(const JackNetUnixSocket& socket) { if (this != &socket) { fSockfd = 0; fPort = socket.fPort; fSendAddr = socket.fSendAddr; fRecvAddr = socket.fRecvAddr; } return *this; } //socket*********************************************************************************************************** int JackNetUnixSocket::NewSocket() { if (fSockfd) { Close(); Reset(); } fSockfd = socket(AF_INET, SOCK_DGRAM, 0); /* Enable address reuse */ int res, on = 1; #ifdef __APPLE__ if ((res = setsockopt(fSockfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) < 0) { #else if ((res = setsockopt(fSockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) { #endif StrError(NET_ERROR_CODE); } int tos = 0; /* see */ /* DSCP Field Hex/Bin/Dec Layer 2 Prio Traffic Type Acronym WMM Access Category 0x38 / 111000 / 56 7 Network Control NC AC_VO 0x30 / 110000 / 48 6 Voice VO AC_VO 0x28 / 101000 / 40 5 Video VI AC_VI 0x20 / 100000 / 32 4 Controlled Load CL AC_VI 0x18 / 011000 / 24 3 Excellent Effort EE AC_BE 0x10 / 010000 / 16 2 Spare -- AC_BK 0x08 / 001000 / 8 1 Background BK AC_BK 0x00 / 000000 / 0 0 Best Effort BE AC_BE */ /* socklen_t len = sizeof(tos); res = getsockopt(fSockfd, IPPROTO_IP, IP_TOS, &tos, &len); printf("getsockopt IPPROTO_IP res = %d tos = %d\n", res, tos); tos = 46 * 4; // see res = setsockopt(fSockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); printf("setsockopt IPPROTO_IP res = %d tos = %d\n", res, tos ); res = getsockopt(fSockfd, IPPROTO_IP, IP_TOS, &tos, &len); printf("getsockopt IPPROTO_IP res = %d tos = %d\n", res, tos); */ return fSockfd; } bool JackNetUnixSocket::IsLocal(char* ip) { if (strcmp(ip, "127.0.0.1") == 0) { return true; } char host_name[32]; gethostname(host_name, sizeof(host_name)); struct hostent* host = gethostbyname(host_name); if (host) { for (int i = 0; host->h_addr_list[i] != 0; ++i) { struct in_addr addr; memcpy(&addr, host->h_addr_list[i], sizeof(struct in_addr)); if (strcmp(inet_ntoa(addr), ip) == 0) { return true; } } return false; } else { return false; } } int JackNetUnixSocket::Bind() { return bind(fSockfd, reinterpret_cast(&fRecvAddr), sizeof(socket_address_t)); } int JackNetUnixSocket::BindWith(const char* ip) { int addr_conv = inet_aton(ip, &fRecvAddr.sin_addr); if (addr_conv < 0) { return addr_conv; } return Bind(); } int JackNetUnixSocket::BindWith(int port) { fRecvAddr.sin_port = htons(port); return Bind(); } int JackNetUnixSocket::Connect() { return connect(fSockfd, reinterpret_cast(&fSendAddr), sizeof(socket_address_t)); } int JackNetUnixSocket::ConnectTo(const char* ip) { int addr_conv = inet_aton(ip, &fSendAddr.sin_addr); if (addr_conv < 0) { return addr_conv; } return Connect(); } void JackNetUnixSocket::Close() { if (fSockfd) { close(fSockfd); } fSockfd = 0; } void JackNetUnixSocket::Reset() { fSendAddr.sin_family = AF_INET; fSendAddr.sin_port = htons(fPort); fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; fRecvAddr.sin_port = htons(fPort); fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&fRecvAddr.sin_zero, 0, 8); } bool JackNetUnixSocket::IsSocket() { return(fSockfd) ? true : false; } //IP/PORT*********************************************************************************************************** void JackNetUnixSocket::SetPort(int port) { fPort = port; fSendAddr.sin_port = htons(port); fRecvAddr.sin_port = htons(port); } int JackNetUnixSocket::GetPort() { return fPort; } //address*********************************************************************************************************** int JackNetUnixSocket::SetAddress(const char* ip, int port) { int addr_conv = inet_aton(ip, &fSendAddr.sin_addr); if (addr_conv < 0) { return addr_conv; } fSendAddr.sin_port = htons(port); return 0; } char* JackNetUnixSocket::GetSendIP() { return inet_ntoa(fSendAddr.sin_addr); } char* JackNetUnixSocket::GetRecvIP() { return inet_ntoa(fRecvAddr.sin_addr); } //utility************************************************************************************************************ int JackNetUnixSocket::GetName(char* name) { return gethostname(name, 255); } int JackNetUnixSocket::JoinMCastGroup(const char* ip) { struct ip_mreq multicast_req; inet_aton(ip, &multicast_req.imr_multiaddr); multicast_req.imr_interface.s_addr = htonl(INADDR_ANY); return SetOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof(multicast_req)); } //options************************************************************************************************************ int JackNetUnixSocket::SetOption(int level, int optname, const void* optval, socklen_t optlen) { return setsockopt(fSockfd, level, optname, optval, optlen); } int JackNetUnixSocket::GetOption(int level, int optname, void* optval, socklen_t* optlen) { return getsockopt(fSockfd, level, optname, optval, optlen); } //timeout************************************************************************************************************ #if defined(__sun__) || defined(sun) int JackNetUnixSocket::SetTimeOut(int us) { int flags; fTimeOut = us; if ((flags = fcntl(fSockfd, F_GETFL, 0)) < 0) { jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_GETFL"); return -1; } flags |= O_NONBLOCK; if (fcntl(fSockfd, F_SETFL, flags) < 0) { jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_SETFL"); return 1; } return 0; } int JackNetUnixSocket::WaitRead() { if (fTimeOut > 0) { struct timeval tv; fd_set fdset; ssize_t res; tv.tv_sec = fTimeOut / 1000000; tv.tv_usec = fTimeOut % 1000000; FD_ZERO(&fdset); FD_SET(fSockfd, &fdset); do { res = select(fSockfd + 1, &fdset, NULL, NULL, &tv); } while (res < 0 && errno == EINTR); if (res < 0) { return res; } else if (res == 0) { errno = ETIMEDOUT; return -1; } } return 0; } int JackNetUnixSocket::WaitWrite() { if (fTimeOut > 0) { struct timeval tv; fd_set fdset; ssize_t res; tv.tv_sec = fTimeOut / 1000000; tv.tv_usec = fTimeOut % 1000000; FD_ZERO(&fdset); FD_SET(fSockfd, &fdset); do { res = select(fSockfd + 1, NULL, &fdset, NULL, &tv); } while (res < 0 && errno == EINTR); if (res < 0) { return res; } else if (res == 0) { errno = ETIMEDOUT; return -1; } } return 0; } #else int JackNetUnixSocket::SetTimeOut(int us) { jack_log("JackNetUnixSocket::SetTimeout %d usecs", us); struct timeval timeout; //less than 1 sec if (us < 1000000) { timeout.tv_sec = 0; timeout.tv_usec = us; } else { //more than 1 sec float sec = float(us) / 1000000.f; timeout.tv_sec = (int)sec; float usec = (sec - float(timeout.tv_sec)) * 1000000; timeout.tv_usec =(int)usec; } return SetOption(SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); } #endif //local loop********************************************************************************************************** int JackNetUnixSocket::SetLocalLoop() { char disable = 0; return SetOption(IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof(disable)); } //network operations************************************************************************************************** int JackNetUnixSocket::SendTo(const void* buffer, size_t nbytes, int flags) { #if defined(__sun__) || defined(sun) if (WaitWrite() < 0) { return -1; } #endif int res; if ((res = sendto(fSockfd, buffer, nbytes, flags, reinterpret_cast(&fSendAddr), sizeof(socket_address_t))) < 0) { jack_error("SendTo fd = %ld err = %s", fSockfd, strerror(errno)); } return res; } int JackNetUnixSocket::SendTo(const void* buffer, size_t nbytes, int flags, const char* ip) { int addr_conv = inet_aton(ip, &fSendAddr.sin_addr); if (addr_conv < 1) { return addr_conv; } fSendAddr.sin_port = htons(fPort); #if defined(__sun__) || defined(sun) if (WaitWrite() < 0) { return -1; } #endif return SendTo(buffer, nbytes, flags); } int JackNetUnixSocket::Send(const void* buffer, size_t nbytes, int flags) { #if defined(__sun__) || defined(sun) if (WaitWrite() < 0) { return -1; } #endif int res; if ((res = send(fSockfd, buffer, nbytes, flags)) < 0) { jack_error("Send fd = %ld err = %s", fSockfd, strerror(errno)); } return res; } int JackNetUnixSocket::RecvFrom(void* buffer, size_t nbytes, int flags) { socklen_t addr_len = sizeof(socket_address_t); #if defined(__sun__) || defined(sun) if (WaitRead() < 0) { return -1; } #endif int res; if ((res = recvfrom(fSockfd, buffer, nbytes, flags, reinterpret_cast(&fRecvAddr), &addr_len)) < 0) { jack_error("RecvFrom fd = %ld err = %s", fSockfd, strerror(errno)); } return res; } int JackNetUnixSocket::Recv(void* buffer, size_t nbytes, int flags) { #if defined(__sun__) || defined(sun) if (WaitRead() < 0) { return -1; } #endif int res; if ((res = recv(fSockfd, buffer, nbytes, flags)) < 0) { jack_error("Recv fd = %ld err = %s", fSockfd, strerror(errno)); } return res; } int JackNetUnixSocket::CatchHost(void* buffer, size_t nbytes, int flags) { socklen_t addr_len = sizeof(socket_address_t); #if defined(__sun__) || defined(sun) if (WaitRead() < 0) { return -1; } #endif int res; if ((res = recvfrom(fSockfd, buffer, nbytes, flags, reinterpret_cast(&fSendAddr), &addr_len)) < 0) { jack_log("CatchHost fd = %ld err = %s", fSockfd, strerror(errno)); } return res; } net_error_t JackNetUnixSocket::GetError() { switch (errno) { case EAGAIN: case ETIMEDOUT: return NET_NO_DATA; case ECONNABORTED: case ECONNREFUSED: case ECONNRESET: case EINVAL: case EHOSTDOWN: case EHOSTUNREACH: case ENETDOWN: case ENETUNREACH: return NET_CONN_ERROR; default: //return NET_OP_ERROR; return NET_CONN_ERROR; } } void JackNetUnixSocket::PrintError() { switch (errno) { case EAGAIN: jack_error("JackNetUnixSocket : EAGAIN"); break; case ETIMEDOUT: jack_error("JackNetUnixSocket : ETIMEDOUT"); break; case ECONNABORTED: jack_error("JackNetUnixSocket : ECONNABORTED"); break; case ECONNREFUSED: jack_error("JackNetUnixSocket : ECONNREFUSED"); break; case ECONNRESET: jack_error("JackNetUnixSocket : ECONNRESET"); break; case EINVAL: jack_error("JackNetUnixSocket : EINVAL"); break; case EHOSTDOWN: jack_error("JackNetUnixSocket : EHOSTDOWN"); break; case EHOSTUNREACH: jack_error("JackNetUnixSocket : EHOSTUNREACH"); break; case ENETDOWN: jack_error("JackNetUnixSocket : ENETDOWN"); break; case ENETUNREACH: jack_error("JackNetUnixSocket : ENETUNREACH"); break; default: jack_error("JackNetUnixSocket : %d", errno); break; } } } 1.9.12~dfsg/posix/JackSocket.cpp0000644000000000000000000002156713214314510015242 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackSocket.h" #include "JackConstants.h" #include "JackTools.h" #include "JackError.h" #include "promiscuous.h" #include #include #include #include namespace Jack { static void BuildName(const char* client_name, char* res, const char* dir, int which, int size, bool promiscuous) { char ext_client_name[SYNC_MAX_NAME_SIZE + 1]; JackTools::RewriteName(client_name, ext_client_name); if (promiscuous) { snprintf(res, size, "%s/jack_%s_%d", dir, ext_client_name, which); } else { snprintf(res, size, "%s/jack_%s_%d_%d", dir, ext_client_name, JackTools::GetUID(), which); } } JackClientSocket::JackClientSocket(): JackClientRequestInterface(), fSocket(-1), fTimeOut(0) { const char* promiscuous = getenv("JACK_PROMISCUOUS_SERVER"); fPromiscuous = (promiscuous != NULL); fPromiscuousGid = jack_group2gid(promiscuous); } JackClientSocket::JackClientSocket(int socket): JackClientRequestInterface(), fSocket(socket),fTimeOut(0), fPromiscuous(false), fPromiscuousGid(-1) {} #if defined(__sun__) || defined(sun) void JackClientSocket::SetReadTimeOut(long sec) { int flags; fTimeOut = sec; if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_GETFL"); return; } flags |= O_NONBLOCK; if (fcntl(fSocket, F_SETFL, flags) < 0) { jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_SETFL"); return; } } void JackClientSocket::SetWriteTimeOut(long sec) { int flags; fTimeOut = sec; if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_GETFL"); return; } flags |= O_NONBLOCK; if (fcntl(fSocket, F_SETFL, flags) < 0) { jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_SETFL"); return; } } #else void JackClientSocket::SetReadTimeOut(long sec) { struct timeval timout; timout.tv_sec = sec; timout.tv_usec = 0; if (setsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timout, sizeof(timeval)) < 0) { jack_error("SetReadTimeOut fd = %ld err = %s", fSocket, strerror(errno)); } } void JackClientSocket::SetWriteTimeOut(long sec) { struct timeval timout; timout.tv_sec = sec ; timout.tv_usec = 0; if (setsockopt(fSocket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timout, sizeof(timeval)) < 0) { jack_error("SetWriteTimeOut fd = %ld err = %s", fSocket, strerror(errno)); } } #endif void JackClientSocket::SetNonBlocking(bool onoff) { if (onoff) { long flags = 0; if (fcntl(fSocket, F_SETFL, flags | O_NONBLOCK) < 0) { jack_error("SetNonBlocking fd = %ld err = %s", fSocket, strerror(errno)); } } } int JackClientSocket::Connect(const char* dir, const char* name, int which) // A revoir : utilisation de "which" { struct sockaddr_un addr; if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { jack_error("Cannot create socket err = %s", strerror(errno)); return -1; } addr.sun_family = AF_UNIX; BuildName(name, addr.sun_path, dir, which, sizeof(addr.sun_path), fPromiscuous); jack_log("JackClientSocket::Connect : addr.sun_path %s", addr.sun_path); if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { jack_error("Cannot connect to server socket err = %s", strerror(errno)); close(fSocket); return -1; } #ifdef __APPLE__ int on = 1; if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) { jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fSocket, strerror(errno)); } #endif return 0; } int JackClientSocket::Close() { jack_log("JackClientSocket::Close"); if (fSocket > 0) { shutdown(fSocket, SHUT_RDWR); close(fSocket); fSocket = -1; return 0; } else { return -1; } } int JackClientSocket::Read(void* data, int len) { int res; #if defined(__sun__) || defined(sun) if (fTimeOut > 0) { struct timeval tv; fd_set fdset; ssize_t res; tv.tv_sec = fTimeOut; tv.tv_usec = 0; FD_ZERO(&fdset); FD_SET(fSocket, &fdset); do { res = select(fSocket + 1, &fdset, NULL, NULL, &tv); } while (res < 0 && errno == EINTR); if (res < 0) { return res; } else if (res == 0) { return -1; } } #endif if ((res = read(fSocket, data, len)) != len) { if (errno == EWOULDBLOCK || errno == EAGAIN) { jack_error("JackClientSocket::Read time out"); return 0; // For a non blocking socket, a read failure is not considered as an error } else if (res != 0) { jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); //return 0; return -1; } else { jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); return -1; } } else { return 0; } } int JackClientSocket::Write(void* data, int len) { int res; #if defined(__sun__) || defined(sun) if (fTimeOut > 0) { struct timeval tv; fd_set fdset; ssize_t res; tv.tv_sec = fTimeOut; tv.tv_usec = 0; FD_ZERO(&fdset); FD_SET(fSocket, &fdset); do { res = select(fSocket + 1, NULL, &fdset, NULL, &tv); } while (res < 0 && errno == EINTR); if (res < 0) { return res; } else if (res == 0) { return -1; } } #endif if ((res = write(fSocket, data, len)) != len) { if (errno == EWOULDBLOCK || errno == EAGAIN) { jack_log("JackClientSocket::Write time out"); return 0; // For a non blocking socket, a write failure is not considered as an error } else if (res != 0) { jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno)); //return 0; return -1; } else { jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno)); return -1; } } else { return 0; } } JackServerSocket::JackServerSocket(): fSocket( -1) { const char* promiscuous = getenv("JACK_PROMISCUOUS_SERVER"); fPromiscuous = (promiscuous != NULL); fPromiscuousGid = jack_group2gid(promiscuous); } int JackServerSocket::Bind(const char* dir, const char* name, int which) // A revoir : utilisation de "which" { struct sockaddr_un addr; if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { jack_error("Cannot create server socket err = %s", strerror(errno)); return -1; } addr.sun_family = AF_UNIX; // Socket name has to be kept in fName to be "unlinked". BuildName(name, fName, dir, which, sizeof(addr.sun_path), fPromiscuous); strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1); jack_log("JackServerSocket::Bind : addr.sun_path %s", addr.sun_path); unlink(fName); // Security... if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { jack_error("Cannot bind server to socket err = %s", strerror(errno)); goto error; } if (listen(fSocket, 100) < 0) { jack_error("Cannot enable listen on server socket err = %s", strerror(errno)); goto error; } if (fPromiscuous && (jack_promiscuous_perms(-1, fName, fPromiscuousGid) < 0)) goto error; return 0; error: unlink(fName); close(fSocket); return -1; } JackClientSocket* JackServerSocket::Accept() { struct sockaddr_un client_addr; socklen_t client_addrlen; memset(&client_addr, 0, sizeof(client_addr)); client_addrlen = sizeof(client_addr); int fd = accept(fSocket, (struct sockaddr*)&client_addr, &client_addrlen); if (fd < 0) { jack_error("Cannot accept new connection err = %s", strerror(errno)); return 0; } else { return new JackClientSocket(fd); } } int JackServerSocket::Close() { if (fSocket > 0) { jack_log("JackServerSocket::Close %s", fName); shutdown(fSocket, SHUT_RDWR); close(fSocket); unlink(fName); fSocket = -1; return 0; } else { return -1; } } } // end of namespace 1.9.12~dfsg/posix/JackSocketClientChannel.cpp0000644000000000000000000001035413214314510017662 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackSocketClientChannel.h" #include "JackRequest.h" #include "JackClient.h" #include "JackGlobals.h" #include "JackError.h" namespace Jack { JackSocketClientChannel::JackSocketClientChannel() :JackGenericClientChannel(), fThread(this) { fRequest = new JackClientSocket(); fNotificationSocket = NULL; } JackSocketClientChannel::~JackSocketClientChannel() { delete fRequest; delete fNotificationSocket; } int JackSocketClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status) { int result = 0; jack_log("JackSocketClientChannel::Open name = %s", name); // Before any server/client call fClient = client; if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) { jack_error("Cannot connect to server socket"); goto error; } // OK so server is there... JackGlobals::fServerRunning = true; // Check name in server ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true); if (result < 0) { int status1 = *status; if (status1 & JackVersionError) { jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); } else { jack_error("Client name = %s conflits with another running client", name); } goto error; } if (fNotificationListenSocket.Bind(jack_client_dir, name_res, 0) < 0) { jack_error("Cannot bind socket"); goto error; } return 0; error: fRequest->Close(); fNotificationListenSocket.Close(); return -1; } void JackSocketClientChannel::Close() { fRequest->Close(); fNotificationListenSocket.Close(); if (fNotificationSocket) { fNotificationSocket->Close(); } } int JackSocketClientChannel::Start() { jack_log("JackSocketClientChannel::Start"); /* To be sure notification thread is started before ClientOpen is called. */ if (fThread.StartSync() != 0) { jack_error("Cannot start Jack client listener"); return -1; } else { return 0; } } void JackSocketClientChannel::Stop() { jack_log("JackSocketClientChannel::Stop"); fThread.Kill(); } bool JackSocketClientChannel::Init() { jack_log("JackSocketClientChannel::Init"); fNotificationSocket = fNotificationListenSocket.Accept(); // No more needed fNotificationListenSocket.Close(); // Setup context if (!jack_tls_set(JackGlobals::fNotificationThread, this)) { jack_error("Failed to set thread notification key"); } if (!fNotificationSocket) { jack_error("JackSocketClientChannel: cannot establish notication socket"); return false; } else { return true; } } bool JackSocketClientChannel::Execute() { JackClientNotification event; JackResult res; if (event.Read(fNotificationSocket) < 0) { jack_error("JackSocketClientChannel read fail"); goto error; } res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); if (event.fSync) { if (res.Write(fNotificationSocket) < 0) { jack_error("JackSocketClientChannel write fail"); goto error; } } return true; error: fNotificationSocket->Close(); fClient->ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE); return false; } } // end of namespace 1.9.12~dfsg/posix/JackFifo.cpp0000644000000000000000000001373613214314510014674 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackFifo.h" #include "JackTools.h" #include "JackError.h" #include "JackPlatformPlug.h" #include #include #include #include #include namespace Jack { void JackFifo::BuildName(const char* client_name, const char* server_name, char* res, int size) { char ext_client_name[SYNC_MAX_NAME_SIZE + 1]; JackTools::RewriteName(client_name, ext_client_name); sprintf(res, "%s/jack_fifo.%d_%s_%s", jack_client_dir, JackTools::GetUID(), server_name, ext_client_name); } bool JackFifo::Signal() { bool res; char c = 0; if (fFifo < 0) { jack_error("JackFifo::Signal name = %s already desallocated!!", fName); return false; } if (fFlush) return true; if ((res = (write(fFifo, &c, sizeof(c)) != sizeof(c)))) { jack_error("JackFifo::Signal name = %s err = %s", fName, strerror(errno)); } return !res; } bool JackFifo::SignalAll() { bool res; char c = 0; if (fFifo < 0) { jack_error("JackFifo::SignalAll name = %s already desallocated!!", fName); return false; } if (fFlush) return true; if ((res = (write(fFifo, &c, sizeof(c)) != sizeof(c)))) { jack_error("JackFifo::SignalAll name = %s err = %s", fName, strerror(errno)); } return !res; } bool JackFifo::Wait() { bool res; char c; if (fFifo < 0) { jack_error("JackFifo::Wait name = %s already desallocated!!", fName); return false; } if ((res = (read(fFifo, &c, sizeof(c)) != sizeof(c)))) { jack_error("JackFifo::Wait name = %s err = %s", fName, strerror(errno)); } return !res; } #ifdef __APPLE__ #warning JackFifo::TimedWait not available : synchronous mode may not work correctly if FIFO are used bool JackFifo::TimedWait(long usec) { return Wait(); } #else // Does not work on OSX ?? bool JackFifo::TimedWait(long usec) { int res; if (fFifo < 0) { jack_error("JackFifo::TimedWait name = %s already desallocated!!", fName); return false; } do { res = poll(&fPoll, 1, usec / 1000); } while (res < 0 && errno == EINTR); if (fPoll.revents & POLLIN) { return Wait(); } else { // Wait failure but we still continue... jack_log("JackFifo::TimedWait name = %s usec = %ld err = %s", fName, usec, strerror(errno)); return true; } } #endif // Server side bool JackFifo::Allocate(const char* name, const char* server_name, int value) { struct stat statbuf; BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackFifo::Allocate name = %s", fName); if (stat(fName, &statbuf) < 0) { if (errno == ENOENT || errno == EPERM) { if (mkfifo(fName, 0666) < 0) { jack_error("Cannot create inter-client FIFO name = %s err = %s", name, strerror(errno)); return false; } } else { jack_error("Cannot check on FIFO %s", name); return false; } } else { if (!S_ISFIFO(statbuf.st_mode)) { jack_error("FIFO name = %s already exists, but is not a FIFO", name); return false; } } if ((fFifo = open(fName, O_RDWR | O_CREAT, 0666)) < 0) { jack_error("Cannot open FIFO name = %s err = %s", name, strerror(errno)); return false; } else { fPoll.fd = fFifo; fPoll.events = POLLERR | POLLIN | POLLHUP | POLLNVAL; return true; } } // Client side bool JackFifo::ConnectAux(const char* name, const char* server_name, int access) { BuildName(name, server_name, fName, sizeof(fName)); jack_log("JackFifo::ConnectAux name = %s", fName); // Temporary... if (fFifo >= 0) { jack_log("Already connected name = %s", name); return true; } if ((fFifo = open(fName, access)) < 0) { jack_error("Connect: can't connect named fifo name = %s err = %s", fName, strerror(errno)); return false; } else { fPoll.fd = fFifo; fPoll.events = POLLERR | POLLIN | POLLHUP | POLLNVAL; return true; } } bool JackFifo::Connect(const char* name, const char* server_name) { return ConnectAux(name, server_name, O_RDWR); } bool JackFifo::ConnectOutput(const char* name, const char* server_name) { return ConnectAux(name, server_name, O_WRONLY | O_NONBLOCK); } bool JackFifo::ConnectInput(const char* name, const char* server_name) { return ConnectAux(name, server_name, O_RDONLY); } bool JackFifo::Disconnect() { if (fFifo >= 0) { jack_log("JackFifo::Disconnect %s", fName); if (close(fFifo) != 0) { jack_error("Disconnect: can't disconnect named fifo name = %s err = %s", fName, strerror(errno)); return false; } else { fFifo = -1; return true; } } else { return true; } } // Server side : destroy the fifo void JackFifo::Destroy() { if (fFifo > 0) { jack_log("JackFifo::Destroy name = %s", fName); unlink(fName); if (close(fFifo) != 0) { jack_error("Destroy: can't destroy fifo name = %s err = %s", fName, strerror(errno)); } fFifo = -1; } else { jack_error("JackFifo::Destroy fifo < 0"); } } } // end of namespace 1.9.12~dfsg/posix/JackPosixMutex.h0000644000000000000000000000313113214314510015567 0ustar rootroot/* Copyright (C) 2006 Grame This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France grame@grame.fr */ #ifndef __JackPosixMutex__ #define __JackPosixMutex__ #include "JackException.h" #include "JackCompilerDeps.h" #include #include #include namespace Jack { /*! \brief Mutex abstraction. */ class SERVER_EXPORT JackBasePosixMutex { protected: pthread_mutex_t fMutex; pthread_t fOwner; public: JackBasePosixMutex(const char* name = NULL); virtual ~JackBasePosixMutex(); bool Lock(); bool Trylock(); bool Unlock(); }; class SERVER_EXPORT JackPosixMutex { protected: pthread_mutex_t fMutex; public: JackPosixMutex(const char* name = NULL); virtual ~JackPosixMutex(); bool Lock(); bool Trylock(); bool Unlock(); }; } // namespace #endif 1.9.12~dfsg/posix/JackSocketServerNotifyChannel.cpp0000644000000000000000000000401513214314510021100 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackSocketServerNotifyChannel.h" #include "JackError.h" #include "JackRequest.h" #include "JackConstants.h" #include "JackNotification.h" #include "JackServerGlobals.h" namespace Jack { int JackSocketServerNotifyChannel::Open(const char* server_name) { if (fRequestSocket.Connect(jack_server_dir, server_name, 0) < 0) { jack_error("Cannot connect to server socket"); return -1; } else { fRequestSocket.SetNonBlocking(true); return 0; } } void JackSocketServerNotifyChannel::Close() { fRequestSocket.Close(); } /* The requirement is that the Notification from RT thread can be delivered... not sure using a socket is adequate here... Can the write operation block? A non blocking write operation shoud be used : check if write can succeed, and ignore the notification otherwise (since its mainly used for XRun, ignoring a notification is OK, successive XRun will come...) */ void JackSocketServerNotifyChannel::Notify(int refnum, int notify, int value) { JackClientNotificationRequest req(refnum, notify, value); if (req.Write(&fRequestSocket) < 0) { jack_error("Could not write notification ref = %d notify = %d", refnum, notify); } } void JackSocketServerNotifyChannel::NotifyQuit() { Notify(-1, kQUIT, 0); } } // end of namespace 1.9.12~dfsg/posix/JackPosixProcessSync.h0000644000000000000000000000335013214314510016743 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPosixProcessSync__ #define __JackPosixProcessSync__ #include "JackPosixMutex.h" #include "JackException.h" #include #include namespace Jack { /*! \brief A synchronization primitive built using a condition variable. */ class JackPosixProcessSync : public JackBasePosixMutex { private: pthread_cond_t fCond; // Condition variable public: JackPosixProcessSync(const char* name = NULL):JackBasePosixMutex() { int res = pthread_cond_init(&fCond, NULL); ThrowIf(res != 0, JackException("JackBasePosixMutex: could not init the cond variable")); } virtual ~JackPosixProcessSync() { pthread_cond_destroy(&fCond); } bool TimedWait(long usec); bool LockedTimedWait(long usec); void Wait(); void LockedWait(); void Signal(); void LockedSignal(); void SignalAll(); void LockedSignalAll(); }; } // end of namespace #endif 1.9.12~dfsg/posix/JackSocket.h0000644000000000000000000000421513214314510014676 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSocket__ #define __JackSocket__ #include #include #include #include #include #include #include #include #include "JackChannel.h" namespace Jack { /*! \brief Client socket. */ class JackClientSocket : public detail::JackClientRequestInterface { private: int fSocket; int fTimeOut; bool fPromiscuous; int fPromiscuousGid; public: JackClientSocket(); JackClientSocket(int socket); int Connect(const char* dir, const char* name, int which); int Close(); int Read(void* data, int len); int Write(void* data, int len); int GetFd() { return fSocket; } void SetReadTimeOut(long sec); void SetWriteTimeOut(long sec); void SetNonBlocking(bool onoff); }; /*! \brief Server socket. */ #define SOCKET_MAX_NAME_SIZE 256 class JackServerSocket { private: int fSocket; char fName[SOCKET_MAX_NAME_SIZE]; bool fPromiscuous; int fPromiscuousGid; public: JackServerSocket(); ~JackServerSocket() {} int Bind(const char* dir, const char* name, int which); JackClientSocket* Accept(); int Close(); int GetFd() { return fSocket; } }; } // end of namespace #endif 1.9.12~dfsg/posix/JackSocketServerNotifyChannel.h0000644000000000000000000000236013214314510020546 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSocketServerNotifyChannel__ #define __JackSocketServerNotifyChannel__ #include "JackSocket.h" namespace Jack { /*! \brief JackServerNotifyChannel using sockets. */ class JackSocketServerNotifyChannel { private: JackClientSocket fRequestSocket; public: JackSocketServerNotifyChannel() {} int Open(const char* server_name); void Close(); void Notify(int refnum, int notify, int value); void NotifyQuit(); }; } // end of namespace #endif 1.9.12~dfsg/posix/JackPosixThread.cpp0000644000000000000000000002213013214314510016227 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackPosixThread.h" #include "JackError.h" #include "JackTime.h" #include "JackGlobals.h" #include // for memset #include // for _POSIX_PRIORITY_SCHEDULING check //#define JACK_SCHED_POLICY SCHED_RR #define JACK_SCHED_POLICY SCHED_FIFO namespace Jack { void* JackPosixThread::ThreadHandler(void* arg) { JackPosixThread* obj = (JackPosixThread*)arg; JackRunnableInterface* runnable = obj->fRunnable; int err; if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) { jack_error("pthread_setcanceltype err = %s", strerror(err)); } // Signal creation thread when started with StartSync jack_log("JackPosixThread::ThreadHandler : start"); obj->fStatus = kIniting; // Call Init method if (!runnable->Init()) { jack_error("Thread init fails: thread quits"); return 0; } obj->fStatus = kRunning; // If Init succeed, start the thread loop bool res = true; while (obj->fStatus == kRunning && res) { res = runnable->Execute(); } jack_log("JackPosixThread::ThreadHandler : exit"); pthread_exit(0); return 0; // never reached } int JackPosixThread::Start() { fStatus = kStarting; // Check if the thread was correctly started if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; } else { return 0; } } int JackPosixThread::StartSync() { fStatus = kStarting; if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; } else { int count = 0; while (fStatus == kStarting && ++count < 1000) { JackSleep(1000); } return (count == 1000) ? -1 : 0; } } int JackPosixThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) { pthread_attr_t attributes; struct sched_param rt_param; pthread_attr_init(&attributes); int res; if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) { jack_error("Cannot request joinable thread creation for thread res = %d", res); return -1; } if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) { jack_error("Cannot set scheduling scope for thread res = %d", res); return -1; } if (realtime) { jack_log("JackPosixThread::StartImp : create RT thread"); if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) { jack_error("Cannot request explicit scheduling for RT thread res = %d", res); return -1; } if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) { jack_error("Cannot set RR scheduling class for RT thread res = %d", res); return -1; } memset(&rt_param, 0, sizeof(rt_param)); rt_param.sched_priority = priority; if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { jack_error("Cannot set scheduling priority for RT thread res = %d", res); return -1; } } else { jack_log("JackPosixThread::StartImp : create non RT thread"); } if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) { jack_error("Cannot set thread stack size res = %d", res); return -1; } if ((res = JackGlobals::fJackThreadCreator(thread, &attributes, start_routine, arg))) { jack_error("Cannot create thread res = %d", res); return -1; } pthread_attr_destroy(&attributes); return 0; } int JackPosixThread::Kill() { if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Kill"); void* status; pthread_cancel(fThread); pthread_join(fThread, &status); fStatus = kIdle; fThread = (jack_native_thread_t)NULL; return 0; } else { return -1; } } int JackPosixThread::Stop() { if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Stop"); void* status; fStatus = kIdle; // Request for the thread to stop pthread_join(fThread, &status); fThread = (jack_native_thread_t)NULL; return 0; } else { return -1; } } int JackPosixThread::KillImp(jack_native_thread_t thread) { if (thread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Kill"); void* status; pthread_cancel(thread); pthread_join(thread, &status); return 0; } else { return -1; } } int JackPosixThread::StopImp(jack_native_thread_t thread) { if (thread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Stop"); void* status; pthread_join(thread, &status); return 0; } else { return -1; } } int JackPosixThread::AcquireRealTime() { return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; } int JackPosixThread::AcquireSelfRealTime() { return AcquireRealTimeImp(pthread_self(), fPriority); } int JackPosixThread::AcquireRealTime(int priority) { fPriority = priority; return AcquireRealTime(); } int JackPosixThread::AcquireSelfRealTime(int priority) { fPriority = priority; return AcquireSelfRealTime(); } int JackPosixThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) { struct sched_param rtparam; int res; memset(&rtparam, 0, sizeof(rtparam)); rtparam.sched_priority = priority; jack_log("JackPosixThread::AcquireRealTimeImp priority = %d", priority); if ((res = pthread_setschedparam(thread, JACK_SCHED_POLICY, &rtparam)) != 0) { jack_error("Cannot use real-time scheduling (RR/%d)" "(%d: %s)", rtparam.sched_priority, res, strerror(res)); return -1; } return 0; } int JackPosixThread::DropRealTime() { return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1; } int JackPosixThread::DropSelfRealTime() { return DropRealTimeImp(pthread_self()); } int JackPosixThread::DropRealTimeImp(jack_native_thread_t thread) { struct sched_param rtparam; int res; memset(&rtparam, 0, sizeof(rtparam)); rtparam.sched_priority = 0; if ((res = pthread_setschedparam(thread, SCHED_OTHER, &rtparam)) != 0) { jack_error("Cannot switch to normal scheduling priority(%s)", strerror(errno)); return -1; } return 0; } jack_native_thread_t JackPosixThread::GetThreadID() { return fThread; } bool JackPosixThread::IsThread() { return pthread_self() == fThread; } void JackPosixThread::Terminate() { jack_log("JackPosixThread::Terminate"); pthread_exit(0); } SERVER_EXPORT void ThreadExit() { jack_log("ThreadExit"); pthread_exit(0); } } // end of namespace bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr) { #if defined(_POSIX_PRIORITY_SCHEDULING) && !defined(__APPLE__) int min, max; min = sched_get_priority_min(JACK_SCHED_POLICY); if (min == -1) { jack_error("sched_get_priority_min() failed."); return false; } max = sched_get_priority_max(JACK_SCHED_POLICY); if (max == -1) { jack_error("sched_get_priority_max() failed."); return false; } *min_ptr = min; *max_ptr = max; return true; #else return false; #endif } bool jack_tls_allocate_key(jack_tls_key *key_ptr) { int ret; ret = pthread_key_create(key_ptr, NULL); if (ret != 0) { jack_error("pthread_key_create() failed with error %d", ret); return false; } return true; } bool jack_tls_free_key(jack_tls_key key) { int ret; ret = pthread_key_delete(key); if (ret != 0) { jack_error("pthread_key_delete() failed with error %d", ret); return false; } return true; } bool jack_tls_set(jack_tls_key key, void *data_ptr) { int ret; ret = pthread_setspecific(key, (const void *)data_ptr); if (ret != 0) { jack_error("pthread_setspecific() failed with error %d", ret); return false; } return true; } void *jack_tls_get(jack_tls_key key) { return pthread_getspecific(key); } 1.9.12~dfsg/posix/JackNetUnixSocket.h0000644000000000000000000000650613214314510016216 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackNetUnixSocket__ #define __JackNetUnixSocket__ #include "JackNetSocket.h" #include #include #include #include #include namespace Jack { #define NET_ERROR_CODE errno #define SOCKET_ERROR -1 #define StrError strerror typedef struct sockaddr socket_address_t; typedef struct in_addr address_t; //JackNetUnixSocket******************************************** class SERVER_EXPORT JackNetUnixSocket { private: int fSockfd; int fPort; int fTimeOut; struct sockaddr_in fSendAddr; struct sockaddr_in fRecvAddr; #if defined(__sun__) || defined(sun) int WaitRead(); int WaitWrite(); #endif public: JackNetUnixSocket(); JackNetUnixSocket(const char* ip, int port); JackNetUnixSocket(const JackNetUnixSocket&); ~JackNetUnixSocket(); JackNetUnixSocket& operator=(const JackNetUnixSocket& socket); //socket management int NewSocket(); int Bind(); int BindWith(const char* ip); int BindWith(int port); int Connect(); int ConnectTo(const char* ip); void Close(); void Reset(); bool IsSocket(); //IP/PORT management void SetPort(int port); int GetPort(); //address management int SetAddress(const char* ip, int port); char* GetSendIP(); char* GetRecvIP(); //utility int GetName(char* name); int JoinMCastGroup(const char* mcast_ip); //options management int SetOption(int level, int optname, const void* optval, socklen_t optlen); int GetOption(int level, int optname, void* optval, socklen_t* optlen); //timeout int SetTimeOut(int us); //disable local loop int SetLocalLoop(); bool IsLocal(char* ip); //network operations int SendTo(const void* buffer, size_t nbytes, int flags); int SendTo(const void* buffer, size_t nbytes, int flags, const char* ip); int Send(const void* buffer, size_t nbytes, int flags); int RecvFrom(void* buffer, size_t nbytes, int flags); int Recv(void* buffer, size_t nbytes, int flags); int CatchHost(void* buffer, size_t nbytes, int flags); //error management net_error_t GetError(); void PrintError(); }; } #endif 1.9.12~dfsg/svnversion_regenerate.sh0000755000000000000000000000246613214314510016324 0ustar rootroot#!/bin/bash #set -x if test $# -ne 1 -a $# -ne 2 then echo "Usage: "`basename "$0"`" [define_name]" exit 1 fi OUTPUT_FILE="`pwd`/${1}" TEMP_FILE="${OUTPUT_FILE}.tmp" #echo svnversion... #pwd #echo "$OUTPUT_FILE" #echo "$TEMP_FILE" # The script should reside in the toplevel source directory which sould contain # all version control files. cd `dirname ${0}` if test $# -eq 2 then DEFINE=${2} else DEFINE=SVN_VERSION fi if test -d .svn then REV=`svnversion 2> /dev/null` else if test -d .git then git status >/dev/null # updates dirty state REV=`git show | grep '^ *git-svn-id:' | sed 's/.*@\([0-9]*\) .*/\1/'` if test ${REV} then test -z "$(git diff-index --name-only HEAD)" || REV="${REV}M" else REV=0+`git rev-parse HEAD` test -z "$(git diff-index --name-only HEAD)" || REV="${REV}-dirty" fi fi fi if test -z ${REV} then REV="unknown" fi echo "#define ${DEFINE} \"${REV}\"" > "${TEMP_FILE}" if test ! -f "${OUTPUT_FILE}" then echo "Generated ${OUTPUT_FILE} (${REV})" cp "${TEMP_FILE}" "${OUTPUT_FILE}" if test $? -ne 0; then exit 1; fi else if ! cmp -s "${OUTPUT_FILE}" "${TEMP_FILE}" then echo "Regenerated ${OUTPUT_FILE} (${REV})" cp "${TEMP_FILE}" "${OUTPUT_FILE}" if test $? -ne 0; then exit 1; fi fi fi rm "${TEMP_FILE}" exit $? 1.9.12~dfsg/README_NETJACK20000644000000000000000000002420713214314510013446 0ustar rootroot------------------------------- NetJack2 for Jack2 ------------------------------- This release includes a version of netjack designed for jack2. Indeed, the original concept has been completely redesigned to better fit to the Jack2 architecture, but also in order to provide additional capabilities, and ultimately a greater robustness. This document describes the major changes between those two systems, then a simple how-to for setting up a basic usage of 'netjack2'. ------------------------------- Major changes and architecture ------------------------------- The biggest difference between netjack1 and netjack2 is the way of slicing audio and midi streams into network packets. For one audio cycle, netjack1 used to take all audio and midi buffers (one per channel), put butt all of them, then send it over the network. The problem is that a network packet has a fixed maximum size, depending on the network infrastructure (for 100mb, it reaches 1500bytes - MTU of the network). The solution is then to slice those buffers into smaller ones, and then send as many packets as we need. This cutting up can be done by network equipments, but it's more efficient and secure to include it in the software data management. Still this slicing brings another issue : all the packets are not pleased with any emission order and are unfortunately received in a random order, thanks to UDP. So we can't deal with data as it comes, we need to re-bufferize incoming streams in order to rebuild complete audio buffers. In netjack2, the main idea is to make this slicing depending on the network capabilities. If we can put only 128 complete audio frames (128 samples for all audio channels) in a network packet, the elementary packet will so carry 128 frames, and in one cycle, we will transmit as many packet as we need. We take the example of 128 frames because it's the current value for 2 channels. This value is determined by taking the maximum 'power of 2' frames we can put in a packet. If we take 2 channels, 4 bytes per sample (float values), we get 8 bytes per frame, with 128 frames, we now have 1024 bytes, so we can put these 1024 bytes in one packet, and add a small header which identify the packet. This technique allows to separate the packets (in time) so they can be received in the order they have been emitted. If the master is running at 512 frames per second, four audio packets are sent per cycle and the slave deals with them as they arrive. With gigabytes networks, the MTU is larger, so we can put more data in one packet (in this example, we can even put the complete cycle in one packet). For midi data, netjack1 used to send the whole buffer, in this example, 512 frames * 4 bytes per sample and per midi port. Those 2048 bytes are in 99% of the time filled to a few bytes, but rarely more. This means that if we have 2 audio and 2 midi channels to transmit, everything happens as if we had 4 audio channels, which is quite a waste of bandwidth. In netjack2, the idea is to take into account that fact, by sending only the useful bytes, and not more. It's completely inappropriate to overload the network with useless data. So we now have : 99% of the time one midi packet (of a few dozen of bytes), followed by four audio packets (in this example). This way of separating audio and midi is quite important. We deal here with network transmissions, and also need to be 'realtime'. We need a system which allow to carry as many audio and midi data streams as we need and can, as if the distant computer was in fact a simple jack client. With all those constraints, we can't avoid packets loss. The better thing to do is to deal with it. But to loose an audio packet is different from skipping a midi one. Indeed, an audio loss leads to audio click, or undesirable, but very short side effect. Whereas a midi data loss can be completely disastrous. Imagine that we play some notes, with sustain, and we loose the sustain 0 value, which stops the effect. The sustain keeps going on on all following notes until the next 'sustain off' event. A simple missing byte can put all the midi system offside (that's the purpose of all the big PANIC buttons on midi softwares...). That's why we need to separate audio (more than one per cycle) from midi (one packet at 99% of the time). If we loose an audio packet, we probably still have an available midi packet, so we can use what we received, even if some audio is missing. Those audio and midi packets are preceded by a synchronization packet, which will make the slave directly synchronized on the master's cycle rhythm. This packet also carries transport data. Thus it's actually possible to synchronize also transport. This feature goes a little further than in netjack1. The idea here is to make every computer of the network fully synchronized on the master's transport. That means the master needs to know the state of every slow sync clients of each of its slaves. The master can now manage the transport state (especially the 'rolling' state) of each slave thus the main transport waits for the last slow sync client before turning 'rolling'. By doing this, the transport can start (roll) in the same cycle for every computers managed by the master. The second main difference between netjack1 and netjack2 is the way the two computers (master and slave) synchronize their parameters and launch. In netjack1, once the slave configured (by the command line) and launched, it was waiting for the first incoming packet to synchronize (launch its first audio cycle) then run. The two computers needed to be configured separately but with the same parameters to run correctly. In netjack2, the only thing you have to set for the slave is its number of in/out midi and audio channels. No more need to choose and set parameters depending on the master, they are automatically determined and communicated to the slave. This first synchronization step uses a multicast communication, no more need to know by advance all the IP addresses. The slave says on a multicast address "hey, I'm available". A master get the message, and communicate parameterers to the slave. Once synchronization done, data transfers can start. Moreover, the master being still listening on the multicast address, it can catch other slaves and manage them (create a jack client to communicate with the slave, and neatly close everything when the slave is gone). The loaded internal client is no longer only an interface for the slave, like in netjack1. It's now called 'network manager', it doesn't deal with audio or midi, just with some kind of 'network logistical messages'. The manager automatically create a new internal client as soon as a new slave is seen on the network (by sending messages on the multicast address the manager is listening on). This manager is also able to remove one of its internal client as soon as a slave has left the network. This conception allow a complete separation of audio exchanges from parameterers and management. The 'unloading' of the internal client (the manager) will cause a full cleaning of the infrastructure. The jack clients are all removed from the server, the slave are all turned available again, ready to be caught by another master etc. When a slave quits, it's also automatically removed from the manager's slaves list. ------------------------------- How-to use this ? ------------------------------- Netjackmp is very simple to use. On the master's side, an internal client deals with the slaves, and the slaves themselves are classical jack servers running under a 'network audio driver'. The difference between the two versions is that the master now has a manager, which takes care of the slaves, while listening on the multicast address and create a new master as soon as a slave is available. But everything is transparent to the user, that's why it uses multicast (someone says "hello", and anyone who wants to hear it just has to listen). So, just compile and install Jack2 as you are used to, on linux, using './waf configure', './waf' and './waf install' as root. On macosx, you can use the xcode project. On Windows, you can use the Code::Blocks workspace (you also have a small script to make an all in one installer). On the master, just launch a classical jack server, the period size doesn't matter. Then, load the network manager using jack_load : 'jack_load netmanager' This will load the internal client, which will wait for an available slave (see the message window on QjackCtl - or the console output). If you want to listen to a specific multicast socket, you can add some options. To specify a complete command line, you can use : 'jack_load netmanager -i"-a xxx.xxx.xxx.xxx -p udp_port"' If you set another multicast address or port, you have to set the same on the slave's side. The default value should be working in many cases. On the slave, just launch a new jack server using : 'jackd -R -d net' As in a standard backend in Jack2, you can use '-S' (synchronous mode). The asynchronous mode (without '-S') allows to send the computed data during the next cycle. In synchronous mode, data are sent back at the end of the cycle, that means after the process. You can specify some options, like '-n name' (will give a name to the slave, default is the network hostname), '-C input_ports' (the number of master-->slave channels), '-P output_ports' (the number of slave-->master channels), default is 2 ; or '-i midi_in_ports' and '-o midi_out_ports', default is 0. If you set multicast address or port on the master, you can add '-a xxx.xxx.xxx.xxx' and '-p udp_port'. Latency (-n) is the number of buffers added in network transmission. Zero is for cases when the audio buffers can be sent to the other size, transformed by the process and returned in the same cycle. By default latency is 5 buffers. For additional informations, you can go to the NetJack2 Wiki at : http://trac.jackaudio.org/wiki/WalkThrough/User/NetJack2. ------------------------------- What's next ? ------------------------------- The development of netjack2 continues and some things are always moving... If you use it, please report encountered bugs, ideas or anything you think about. If you have any question, you can subscribe the jackaudio developers mailing list at http://www.jackaudio.org/ or join the IRC channel '#jack' on FreeNode. 1.9.12~dfsg/common/0000755000000000000000000000000013214314510012630 5ustar rootroot1.9.12~dfsg/common/JackWaitThreadedDriver.cpp0000644000000000000000000000433013214314510017646 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackWaitThreadedDriver.h" #include "JackGlobals.h" #include "JackClient.h" #include "JackEngineControl.h" #include "JackException.h" #include "JackError.h" #include "JackTools.h" namespace Jack { bool JackWaitThreadedDriver::Init() { return (fStarter.Start() == 0); } bool JackWaitThreadedDriver::Execute() { SetRealTime(); // Process a null cycle until NetDriver has started while (!fStarter.fRunning && fThread.GetStatus() == JackThread::kRunning) { // Use base class method assert(static_cast(fDriver)); static_cast(fDriver)->ProcessNull(); } return ExecuteReal(); } bool JackWaitThreadedDriver::ExecuteReal() { try { // Switch to keep running even in case of error while (fThread.GetStatus() == JackThread::kRunning) { fDriver->Process(); } return false; } catch (JackNetException& e) { e.PrintMessage(); jack_info("Driver is restarted"); fThread.DropSelfRealTime(); // Thread has been stopped... if (fThread.GetStatus() == JackThread::kIdle) { return false; } // Thread in kIniting status again... fThread.SetStatus(JackThread::kIniting); if (Init()) { // Thread in kRunning status again... fThread.SetStatus(JackThread::kRunning); return true; } return false; } } } // end of namespace 1.9.12~dfsg/common/JackThread.h0000644000000000000000000000743213214314510015007 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackThread__ #define __JackThread__ #include "JackCompilerDeps.h" #include "JackTypes.h" namespace Jack { /*! \brief The base class for runnable objects, that have an Init and Execute method to be called in a thread. */ class JackRunnableInterface { protected: JackRunnableInterface() {} virtual ~JackRunnableInterface() {} public: virtual bool Init() /*! Called once when the thread is started */ { return true; } virtual bool Execute() = 0; /*! Must be implemented by subclasses */ }; namespace detail { /*! \brief The thread base class. */ class SERVER_EXPORT JackThreadInterface { public: enum kThreadState {kIdle, kStarting, kIniting, kRunning}; protected: JackRunnableInterface* fRunnable; int fPriority; bool fRealTime; volatile kThreadState fStatus; int fCancellation; public: JackThreadInterface(JackRunnableInterface* runnable, int priority, bool real_time, int cancellation): fRunnable(runnable), fPriority(priority), fRealTime(real_time), fStatus(kIdle), fCancellation(cancellation) {} kThreadState GetStatus() { return fStatus; } void SetStatus(kThreadState status) { fStatus = status; } void SetParams(UInt64 period, UInt64 computation, UInt64 constraint) // Empty implementation, will only make sense on OSX... {} int Start(); int StartSync(); int Kill(); int Stop(); void Terminate(); int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself jack_native_thread_t GetThreadID(); bool IsThread(); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint); static int DropRealTimeImp(jack_native_thread_t thread); static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); static int StopImp(jack_native_thread_t thread); static int KillImp(jack_native_thread_t thread); }; } } // end of namespace bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr); bool jack_tls_allocate_key(jack_tls_key *key_ptr); bool jack_tls_free_key(jack_tls_key key); bool jack_tls_set(jack_tls_key key, void *data_ptr); void *jack_tls_get(jack_tls_key key); #endif 1.9.12~dfsg/common/JackWaitCallbackDriver.cpp0000644000000000000000000000225513214314510017626 0ustar rootroot/* Copyright (C) 2014 Cédric Schieli This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "JackWaitCallbackDriver.h" namespace Jack { JackWaitCallbackDriver::JackWaitCallbackDriver(JackRestarterDriver* driver) : JackWaitThreadedDriver(driver) { // Self register with the decorated driver so it can restart us assert(driver); driver->SetRestartDriver((JackDriver*)this); } bool JackWaitCallbackDriver::ExecuteReal() { // End the thread and let the callback driver do its job return false; } } // end of namespace 1.9.12~dfsg/common/JackFrameTimer.h0000644000000000000000000000535613214314510015636 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackFrameTimer__ #define __JackFrameTimer__ #include "JackAtomicState.h" #include "JackCompilerDeps.h" #include "types.h" namespace Jack { /*! \brief A structure used for time management. */ PRE_PACKED_STRUCTURE class SERVER_EXPORT JackTimer { friend class JackFrameTimer; private: jack_nframes_t fFrames; jack_time_t fCurrentWakeup; jack_time_t fCurrentCallback; jack_time_t fNextWakeUp; float fPeriodUsecs; float fFilterOmega; /* set once, never altered */ bool fInitialized; public: JackTimer(); ~JackTimer() {} jack_nframes_t Time2Frames(jack_time_t time, jack_nframes_t buffer_size); jack_time_t Frames2Time(jack_nframes_t frames, jack_nframes_t buffer_size); jack_nframes_t FramesSinceCycleStart(jack_time_t cur_time, jack_nframes_t frames_rate); int GetCycleTimes(jack_nframes_t* current_frames, jack_time_t* current_usecs, jack_time_t* next_usecs, float* period_usecs); jack_nframes_t CurFrame() { return fFrames; } jack_time_t CurTime() { return fCurrentWakeup; } } POST_PACKED_STRUCTURE; /*! \brief A class using the JackAtomicState to manage jack time. */ PRE_PACKED_STRUCTURE class SERVER_EXPORT JackFrameTimer : public JackAtomicState { private: bool fFirstWakeUp; void IncFrameTimeAux(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs); void InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t period_usecs); public: JackFrameTimer(): fFirstWakeUp(true) {} ~JackFrameTimer() {} void InitFrameTime(); void ResetFrameTime(jack_time_t callback_usecs); void IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs); void ReadFrameTime(JackTimer* timer); } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackMidiAPI.cpp0000644000000000000000000001105013214314510015336 0ustar rootroot/* Copyright (C) 2007 Dmitry Baikov Original JACK MIDI implementation Copyright (C) 2004 Ian Esten This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackError.h" #include "JackMidiPort.h" #include #include #ifdef __cplusplus extern "C" { #endif LIB_EXPORT uint32_t jack_midi_get_event_count(void* port_buffer); LIB_EXPORT int jack_midi_event_get(jack_midi_event_t* event, void* port_buffer, uint32_t event_index); LIB_EXPORT void jack_midi_clear_buffer(void* port_buffer); LIB_EXPORT void jack_midi_reset_buffer(void* port_buffer); LIB_EXPORT size_t jack_midi_max_event_size(void* port_buffer); LIB_EXPORT jack_midi_data_t* jack_midi_event_reserve(void* port_buffer, jack_nframes_t time, size_t data_size); LIB_EXPORT int jack_midi_event_write(void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size); LIB_EXPORT jack_nframes_t jack_midi_get_lost_event_count(void* port_buffer); #ifdef __cplusplus } #endif using namespace Jack; LIB_EXPORT uint32_t jack_midi_get_event_count(void* port_buffer) { JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; if (!buf || !buf->IsValid()) { return 0; } return buf->event_count; } LIB_EXPORT int jack_midi_event_get(jack_midi_event_t *event, void* port_buffer, uint32_t event_index) { JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; if (!buf || !buf->IsValid()) { return -EINVAL; } if (event_index >= buf->event_count) { return -ENOBUFS; } JackMidiEvent* ev = &buf->events[event_index]; event->time = ev->time; event->size = ev->size; event->buffer = ev->GetData(buf); return 0; } LIB_EXPORT void jack_midi_clear_buffer(void* port_buffer) { JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; if (buf && buf->IsValid()) { buf->Reset(buf->nframes); } } LIB_EXPORT void jack_midi_reset_buffer(void* port_buffer) { MidiBufferInit(port_buffer, BUFFER_SIZE_MAX, BUFFER_SIZE_MAX); } LIB_EXPORT size_t jack_midi_max_event_size(void* port_buffer) { JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; if (buf && buf->IsValid()) { return buf->MaxEventSize(); } return 0; } LIB_EXPORT jack_midi_data_t* jack_midi_event_reserve(void* port_buffer, jack_nframes_t time, size_t data_size) { JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; if (! buf) { jack_error("jack_midi_event_reserve: port buffer is set to NULL"); return 0; } if (! buf->IsValid()) { jack_error("jack_midi_event_reserve: port buffer is invalid"); return 0; } if (time >= buf->nframes) { jack_error("jack_midi_event_reserve: time parameter is out of range " "(%lu >= %lu)", time, buf->nframes); return 0; } if (buf->event_count && (buf->events[buf->event_count - 1].time > time)) { jack_error("jack_midi_event_reserve: time parameter is earlier than " "last reserved event"); return 0; } return buf->ReserveEvent(time, data_size); } LIB_EXPORT int jack_midi_event_write(void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size) { JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; if (!buf || !buf->IsValid()) { return -EINVAL; } if (time >= buf->nframes || (buf->event_count && buf->events[buf->event_count - 1].time > time)) { return -EINVAL; } jack_midi_data_t* dest = buf->ReserveEvent(time, data_size); if (!dest) { return -ENOBUFS; } memcpy(dest, data, data_size); return 0; } LIB_EXPORT uint32_t jack_midi_get_lost_event_count(void* port_buffer) { JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; if (buf && buf->IsValid()) { return buf->lost_events; } return 0; } 1.9.12~dfsg/common/JackProfiler.cpp0000644000000000000000000002406213214314510015713 0ustar rootroot/* Copyright (C) 2009 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackProfiler.h" #include "JackServerGlobals.h" #include "JackEngineControl.h" #include "JackLockedEngine.h" #include "JackArgParser.h" #include #include namespace Jack { JackProfilerClient::JackProfilerClient(jack_client_t* client, const char* name) :fClient(client) { char port_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; fRefNum = JackServerGlobals::fInstance->GetEngine()->GetClientRefNum(name); snprintf(port_name, sizeof(port_name) - 1, "%s:scheduling", name); fSchedulingPort = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); snprintf(port_name, sizeof(port_name) - 1, "%s:duration", name); fDurationPort = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); } JackProfilerClient::~JackProfilerClient() { jack_port_unregister(fClient, fSchedulingPort); jack_port_unregister(fClient, fDurationPort); } #ifdef JACK_MONITOR JackProfiler::JackProfiler(jack_client_t* client, const JSList* params) :fClient(client), fLastMeasure(NULL) #else JackProfiler::JackProfiler(jack_client_t* client, const JSList* params) :fClient(client) #endif { jack_log("JackProfiler::JackProfiler"); fCPULoadPort = fDriverPeriodPort = fDriverEndPort = NULL; const JSList* node; const jack_driver_param_t* param; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*)node->data; switch (param->character) { case 'c': fCPULoadPort = jack_port_register(client, "cpu_load", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); break; case 'p': fDriverPeriodPort = jack_port_register(client, "driver_period", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); break; case 'e': fDriverEndPort = jack_port_register(client, "driver_end_time", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); break; } } // Resigster all running clients const char **ports = jack_get_ports(client, NULL, NULL, 0); if (ports) { for (int i = 0; ports[i]; ++i) { std::string str = std::string(ports[i]); ClientRegistration(str.substr(0, str.find_first_of(':')).c_str(), 1, this); } free(ports); } jack_set_process_callback(client, Process, this); jack_set_client_registration_callback(client, ClientRegistration, this); jack_activate(client); } JackProfiler::~JackProfiler() { jack_log("JackProfiler::~JackProfiler"); } void JackProfiler::ClientRegistration(const char* name, int val, void *arg) { #ifdef JACK_MONITOR JackProfiler* profiler = static_cast(arg); // Filter client or "system" name if (strcmp(name, jack_get_client_name(profiler->fClient)) == 0 || strcmp(name, "system") == 0) return; profiler->fMutex.Lock(); if (val) { std::map::iterator it = profiler->fClientTable.find(name); if (it == profiler->fClientTable.end()) { jack_log("Client %s added", name); profiler->fClientTable[name] = new JackProfilerClient(profiler->fClient, name); } } else { std::map::iterator it = profiler->fClientTable.find(name); if (it != profiler->fClientTable.end()) { jack_log("Client %s removed", name); profiler->fClientTable.erase(it); delete((*it).second); } } profiler->fMutex.Unlock(); #endif } int JackProfiler::Process(jack_nframes_t nframes, void* arg) { JackProfiler* profiler = static_cast(arg); if (profiler->fCPULoadPort) { float* buffer_cpu_load = (float*)jack_port_get_buffer(profiler->fCPULoadPort, nframes); float cpu_load = jack_cpu_load(profiler->fClient); for (unsigned int i = 0; i < nframes; i++) { buffer_cpu_load[i] = cpu_load / 100.f; } } #ifdef JACK_MONITOR JackEngineControl* control = JackServerGlobals::fInstance->GetEngineControl(); JackEngineProfiling* engine_profiler = &control->fProfiler; JackTimingMeasure* measure = engine_profiler->GetCurMeasure(); if (profiler->fLastMeasure && profiler->fMutex.Trylock()) { if (profiler->fDriverPeriodPort) { float* buffer_driver_period = (float*)jack_port_get_buffer(profiler->fDriverPeriodPort, nframes); float value1 = (float(measure->fPeriodUsecs) - float(measure->fCurCycleBegin - profiler->fLastMeasure->fCurCycleBegin)) / float(measure->fPeriodUsecs); for (unsigned int i = 0; i < nframes; i++) { buffer_driver_period[i] = value1; } } if (profiler->fDriverEndPort) { float* buffer_driver_end_time = (float*)jack_port_get_buffer(profiler->fDriverEndPort, nframes); float value2 = (float(measure->fPrevCycleEnd - profiler->fLastMeasure->fCurCycleBegin)) / float(measure->fPeriodUsecs); for (unsigned int i = 0; i < nframes; i++) { buffer_driver_end_time[i] = value2; } } std::map::iterator it; for (it = profiler->fClientTable.begin(); it != profiler->fClientTable.end(); it++) { int ref = (*it).second->fRefNum; long d5 = long(measure->fClientTable[ref].fSignaledAt - profiler->fLastMeasure->fCurCycleBegin); long d6 = long(measure->fClientTable[ref].fAwakeAt - profiler->fLastMeasure->fCurCycleBegin); long d7 = long(measure->fClientTable[ref].fFinishedAt - profiler->fLastMeasure->fCurCycleBegin); float* buffer_scheduling = (float*)jack_port_get_buffer((*it).second->fSchedulingPort, nframes); float value3 = float(d6 - d5) / float(measure->fPeriodUsecs); jack_log("Scheduling %f", value3); for (unsigned int i = 0; i < nframes; i++) { buffer_scheduling[i] = value3; } float* buffer_duration = (float*)jack_port_get_buffer((*it).second->fDurationPort, nframes); float value4 = float(d7 - d6) / float(measure->fPeriodUsecs); jack_log("Duration %f", value4); for (unsigned int i = 0; i < nframes; i++) { buffer_duration[i] = value4; } } profiler->fMutex.Unlock(); } profiler->fLastMeasure = measure; #endif return 0; } } // namespace Jack #ifdef __cplusplus extern "C" { #endif #include "driver_interface.h" using namespace Jack; static Jack::JackProfiler* profiler = NULL; SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("profiler", JackDriverNone, "real-time server profiling", &filler); value.i = FALSE; jack_driver_descriptor_add_parameter(desc, &filler, "cpu-load", 'c', JackDriverParamBool, &value, NULL, "Show DSP CPU load", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "driver-period", 'p', JackDriverParamBool, &value, NULL, "Show driver period", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "driver-end-time", 'e', JackDriverParamBool, &value, NULL, "Show driver end time", NULL); return desc; } SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params) { if (profiler) { jack_info("profiler already loaded"); return 1; } jack_log("Loading profiler"); try { profiler = new Jack::JackProfiler(jack_client, params); assert(profiler); return 0; } catch (...) { return 1; } } SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init) { JSList* params = NULL; bool parse_params = true; int res = 1; jack_driver_desc_t* desc = jack_get_descriptor(); Jack::JackArgParser parser ( load_init ); if ( parser.GetArgc() > 0 ) parse_params = parser.ParseParams ( desc, ¶ms ); if (parse_params) { res = jack_internal_initialize ( jack_client, params ); parser.FreeParams ( params ); } return res; } SERVER_EXPORT void jack_finish(void* arg) { Jack::JackProfiler* profiler = static_cast(arg); if (profiler) { jack_log("Unloading profiler"); delete profiler; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/common/JackCompilerDeps.h0000644000000000000000000000143713214314510016165 0ustar rootroot/* Copyright (C) 2004-2005 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCompilerDeps__ #define __JackCompilerDeps__ #include "JackCompilerDeps_os.h" #endif 1.9.12~dfsg/common/JackRequestDecoder.h0000644000000000000000000000316513214314510016515 0ustar rootroot/* Copyright (C) 2012 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackRequestDecoder__ #define __JackRequestDecoder__ #include "JackChannel.h" namespace Jack { class JackServer; struct JackClientOpenRequest; struct JackClientOpenResult; struct JackClientHandlerInterface { virtual void ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult* res) = 0; virtual void ClientRemove(detail::JackChannelTransactionInterface* socket, int refnum) = 0; virtual ~JackClientHandlerInterface() {} }; /*! \brief Request decoder */ class JackRequestDecoder { private: JackServer* fServer; JackClientHandlerInterface* fHandler; public: JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler); virtual ~JackRequestDecoder(); int HandleRequest(detail::JackChannelTransactionInterface* socket, int type); }; } // end of namespace #endif 1.9.12~dfsg/common/JackServerAPI.cpp0000644000000000000000000001434213214314510015731 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackGraphManager.h" #include "JackInternalClient.h" #include "JackServer.h" #include "JackDebugClient.h" #include "JackServerGlobals.h" #include "JackTools.h" #include "JackCompilerDeps.h" #include "JackLockedEngine.h" #ifdef __cplusplus extern "C" { #endif jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status); SERVER_EXPORT jack_client_t * jack_client_open (const char *client_name, jack_options_t options, jack_status_t *status, ...); SERVER_EXPORT int jack_client_close (jack_client_t *client); SERVER_EXPORT int jack_get_client_pid (const char *name); #ifdef __cplusplus } #endif using namespace Jack; jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status) { jack_varargs_t va; /* variable arguments */ jack_status_t my_status; JackClient* client; if (client_name == NULL) { jack_error("jack_client_new called with a NULL client_name"); return NULL; } jack_log("jack_client_new %s", client_name); if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ *status = (jack_status_t)0; /* validate parameters */ if ((options & ~JackOpenOptions)) { int my_status1 = *status | (JackFailure | JackInvalidOption); *status = (jack_status_t)my_status1; return NULL; } /* parse variable arguments */ jack_varargs_init(&va); if (!JackServerGlobals::Init()) { // jack server initialisation int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } if (JACK_DEBUG) { client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode } else { client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable()); } int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; JackServerGlobals::Destroy(); // jack server destruction int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } else { return (jack_client_t*)client; } } jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) { jack_varargs_t va; /* variable arguments */ jack_status_t my_status; JackClient* client; if (client_name == NULL) { jack_error("jack_client_open called with a NULL client_name"); return NULL; } jack_log("jack_client_open %s", client_name); if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ *status = (jack_status_t)0; /* validate parameters */ if ((options & ~JackOpenOptions)) { int my_status1 = *status | (JackFailure | JackInvalidOption); *status = (jack_status_t)my_status1; return NULL; } /* parse variable arguments */ jack_varargs_parse(options, ap, &va); if (!JackServerGlobals::Init()) { // jack server initialisation int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } if (JACK_DEBUG) { client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode } else { client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable()); } int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; JackServerGlobals::Destroy(); // jack server destruction int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } else { return (jack_client_t*)client; } } SERVER_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { JackGlobals::CheckContext("jack_client_open"); try { assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); va_list ap; va_start(ap, status); jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); va_end(ap); JackGlobals::fOpenMutex->Unlock(); return res; } catch (std::bad_alloc& e) { jack_error("Memory allocation error..."); return NULL; } catch (...) { jack_error("Unknown error..."); return NULL; } } SERVER_EXPORT int jack_client_close(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_client_close"); assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); int res = -1; jack_log("jack_client_close"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_client_close called with a NULL client"); } else { res = client->Close(); delete client; JackServerGlobals::Destroy(); // jack server destruction jack_log("jack_client_close res = %d", res); } JackGlobals::fOpenMutex->Unlock(); return res; } SERVER_EXPORT int jack_get_client_pid(const char *name) { return (JackServerGlobals::fInstance != NULL) ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name) : 0; } 1.9.12~dfsg/common/JackAudioAdapterFactory.cpp0000644000000000000000000000570113214314510020022 0ustar rootroot/* Copyright (C) 2008-2012 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioAdapter.h" #include "JackPlatformPlug.h" #include "JackArgParser.h" #include #include #include #ifdef __APPLE__ #include "JackCoreAudioAdapter.h" #define JackPlatformAdapter JackCoreAudioAdapter #endif #ifdef __linux__ #include "JackAlsaAdapter.h" #define JackPlatformAdapter JackAlsaAdapter #endif #if defined(__sun__) || defined(sun) #include "JackOSSAdapter.h" #define JackPlatformAdapter JackOSSAdapter #endif #ifdef WIN32 #include "JackPortAudioAdapter.h" #define JackPlatformAdapter JackPortAudioAdapter #endif #ifdef __cplusplus extern "C" { #endif using namespace Jack; SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params) { jack_log("Loading audioadapter"); Jack::JackAudioAdapter* adapter; jack_nframes_t buffer_size = jack_get_buffer_size(jack_client); jack_nframes_t sample_rate = jack_get_sample_rate(jack_client); try { adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackPlatformAdapter(buffer_size, sample_rate, params), params); assert(adapter); if (adapter->Open() == 0) { return 0; } else { delete adapter; return 1; } } catch (...) { jack_info("audioadapter allocation error"); return 1; } } SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init) { JSList* params = NULL; bool parse_params = true; int res = 1; jack_driver_desc_t* desc = jack_get_descriptor(); Jack::JackArgParser parser(load_init); if (parser.GetArgc() > 0) { parse_params = parser.ParseParams(desc, ¶ms); } if (parse_params) { res = jack_internal_initialize(jack_client, params); parser.FreeParams(params); } return res; } SERVER_EXPORT void jack_finish(void* arg) { Jack::JackAudioAdapter* adapter = static_cast(arg); if (adapter) { jack_log("Unloading audioadapter"); adapter->Close(); delete adapter; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/common/JackSynchro.h0000644000000000000000000000415413214314510015223 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackSynchro__ #define __JackSynchro__ #include "JackConstants.h" namespace Jack { namespace detail { /*! \brief An inter process synchronization primitive. */ class JackSynchro { protected: char fName[SYNC_MAX_NAME_SIZE]; bool fFlush; // If true, signal are "flushed" : used for drivers that do no consume the signal public: JackSynchro(): fFlush(false) {} ~JackSynchro() {} bool Signal() { return true; } bool SignalAll() { return true; } bool Wait() { return true; } bool TimedWait(long usec) { return true; } bool Allocate(const char* name, const char* server_name, int value) { return true; } bool Connect(const char* name, const char* server_name) { return true; } bool ConnectInput(const char* name, const char* server_name) { return true; } bool ConnectOutput(const char* name, const char* server_name) { return true; } bool Disconnect() { return true; } void Destroy() {} void SetFlush(bool mode) { fFlush = mode; } }; } } // end of namespace #endif 1.9.12~dfsg/common/JackSystemDeps.h0000644000000000000000000000146113214314510015674 0ustar rootroot/* Copyright (C) 2004-2006 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackSystemDeps__ #define __JackSystemDeps__ #include "systemdeps.h" #include "JackSystemDeps_os.h" #endif 1.9.12~dfsg/common/promiscuous.c0000644000000000000000000000462413214314510015372 0ustar rootroot/* Copyright (C) 2014-2017 Cédric Schieli This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef WIN32 #include #include #include #include #include #include #include #ifdef __APPLE__ #include #endif #include "JackError.h" #endif int jack_group2gid(const char* group) { #ifdef WIN32 return -1; #else size_t buflen; char *buf; int ret; struct group grp; struct group *result; if (!group || !*group) return -1; ret = strtol(group, &buf, 10); if (!*buf) return ret; /* MacOSX only defines _SC_GETGR_R_SIZE_MAX starting from 10.4 */ #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 buflen = 4096; #else buflen = sysconf(_SC_GETGR_R_SIZE_MAX); if (buflen == -1) buflen = 4096; #endif buf = (char*)malloc(buflen); while (buf && ((ret = getgrnam_r(group, &grp, buf, buflen, &result)) == ERANGE)) { buflen *= 2; buf = (char*)realloc(buf, buflen); } if (!buf) return -1; free(buf); if (ret || !result) return -1; return grp.gr_gid; #endif } #ifndef WIN32 int jack_promiscuous_perms(int fd, const char* path, gid_t gid) { mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; if (gid >= 0) { if (((fd < 0) ? chown(path, -1, gid) : fchown(fd, -1, gid)) < 0) { jack_log("Cannot chgrp %s: %s. Falling back to permissive perms.", path, strerror(errno)); } else { mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; } } if (((fd < 0) ? chmod(path, mode) : fchmod(fd, mode)) < 0) { jack_log("Cannot chmod %s: %s. Falling back to default (umask) perms.", path, strerror(errno)); return -1; } return 0; } #endif 1.9.12~dfsg/common/JackNetAdapter.cpp0000644000000000000000000004511213214314510016157 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackNetAdapter.h" #include "JackException.h" #include "JackServerGlobals.h" #include "JackEngineControl.h" #include "JackArgParser.h" #include namespace Jack { JackNetAdapter::JackNetAdapter(jack_client_t* jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) : JackAudioAdapterInterface(buffer_size, sample_rate), JackNetSlaveInterface(), fThread(this) { jack_log("JackNetAdapter::JackNetAdapter"); /* Global parameter setting : we can't call JackNetSlaveInterface constructor with some parameters before, because we don't have full parametering right now, parameters will be parsed from the param list, and then JackNetSlaveInterface will be filled with proper values. */ char multicast_ip[32]; uint udp_port; GetHostName(fParams.fName, JACK_CLIENT_NAME_SIZE); fSocket.GetName(fParams.fSlaveNetName); fParams.fMtu = DEFAULT_MTU; // Desactivated for now... fParams.fTransportSync = 0; int send_audio = -1; int return_audio = -1; fParams.fSendMidiChannels = 0; fParams.fReturnMidiChannels = 0; fParams.fSampleRate = sample_rate; fParams.fPeriodSize = buffer_size; fParams.fSlaveSyncMode = 1; fParams.fNetworkLatency = NETWORK_DEFAULT_LATENCY; fParams.fSampleEncoder = JackFloatEncoder; fClient = jack_client; // Possibly use env variable const char* default_udp_port = getenv("JACK_NETJACK_PORT"); udp_port = (default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT; const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST"); if (default_multicast_ip) { strcpy(multicast_ip, default_multicast_ip); } else { strcpy(multicast_ip, DEFAULT_MULTICAST_IP); } //options parsing const JSList* node; const jack_driver_param_t* param; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'a' : assert(strlen(param->value.str) < 32); strcpy(multicast_ip, param->value.str); break; case 'p' : udp_port = param->value.ui; break; case 'M' : fParams.fMtu = param->value.i; break; case 'C' : send_audio = param->value.i; break; case 'P' : return_audio = param->value.i; break; case 'n' : strncpy(fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE); break; case 't' : fParams.fTransportSync = param->value.ui; break; #if HAVE_CELT case 'c': if (param->value.i > 0) { fParams.fSampleEncoder = JackCeltEncoder; fParams.fKBps = param->value.i; } break; #endif #if HAVE_OPUS case 'O': if (param->value.i > 0) { fParams.fSampleEncoder = JackOpusEncoder; fParams.fKBps = param->value.i; } break; #endif case 'l' : fParams.fNetworkLatency = param->value.i; if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) { jack_error("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY); throw std::bad_alloc(); } break; case 'q': fQuality = param->value.ui; break; case 'g': fRingbufferCurSize = param->value.ui; fAdaptative = false; break; } } strcpy(fMulticastIP, multicast_ip); // Set the socket parameters fSocket.SetPort(udp_port); fSocket.SetAddress(fMulticastIP, udp_port); // If not set, takes default fParams.fSendAudioChannels = (send_audio == -1) ? 2 : send_audio; // If not set, takes default fParams.fReturnAudioChannels = (return_audio == -1) ? 2 : return_audio; // Set the audio adapter interface channel values SetInputs(fParams.fSendAudioChannels); SetOutputs(fParams.fReturnAudioChannels); // Soft buffers will be allocated later (once network initialization done) fSoftCaptureBuffer = NULL; fSoftPlaybackBuffer = NULL; } JackNetAdapter::~JackNetAdapter() { jack_log("JackNetAdapter::~JackNetAdapter"); if (fSoftCaptureBuffer) { for (int port_index = 0; port_index < fCaptureChannels; port_index++) { delete[] fSoftCaptureBuffer[port_index]; } delete[] fSoftCaptureBuffer; } if (fSoftPlaybackBuffer) { for (int port_index = 0; port_index < fPlaybackChannels; port_index++) { delete[] fSoftPlaybackBuffer[port_index]; } delete[] fSoftPlaybackBuffer; } } //open/close-------------------------------------------------------------------------- int JackNetAdapter::Open() { jack_info("NetAdapter started in %s mode %s Master's transport sync.", (fParams.fSlaveSyncMode) ? "sync" : "async", (fParams.fTransportSync) ? "with" : "without"); if (fThread.StartSync() < 0) { jack_error("Cannot start netadapter thread"); return -1; } return 0; } int JackNetAdapter::Close() { int res = 0; jack_log("JackNetAdapter::Close"); #ifdef JACK_MONITOR fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif if (fThread.Kill() < 0) { jack_error("Cannot kill thread"); res = -1; } fSocket.Close(); return res; } int JackNetAdapter::SetBufferSize(jack_nframes_t buffer_size) { JackAudioAdapterInterface::SetHostBufferSize(buffer_size); return 0; } //thread------------------------------------------------------------------------------ // TODO : if failure, thread exist... need to restart ? bool JackNetAdapter::Init() { jack_log("JackNetAdapter::Init"); //init network connection if (!JackNetSlaveInterface::Init()) { jack_error("JackNetSlaveInterface::Init() error..."); return false; } //then set global parameters if (!SetParams()) { jack_error("SetParams error..."); return false; } //set buffers if (fCaptureChannels > 0) { fSoftCaptureBuffer = new sample_t*[fCaptureChannels]; for (int port_index = 0; port_index < fCaptureChannels; port_index++) { fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize]; fNetAudioCaptureBuffer->SetBuffer(port_index, fSoftCaptureBuffer[port_index]); } } if (fPlaybackChannels > 0) { fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels]; for (int port_index = 0; port_index < fPlaybackChannels; port_index++) { fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize]; fNetAudioPlaybackBuffer->SetBuffer(port_index, fSoftPlaybackBuffer[port_index]); } } //set audio adapter parameters SetAdaptedBufferSize(fParams.fPeriodSize); SetAdaptedSampleRate(fParams.fSampleRate); // Will do "something" on OSX only... fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) { jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } //init done, display parameters SessionParamsDisplay(&fParams); return true; } bool JackNetAdapter::Execute() { try { // Keep running even in case of error while (fThread.GetStatus() == JackThread::kRunning) { if (Process() == SOCKET_ERROR) { return false; } } return false; } catch (JackNetException& e) { // Otherwise just restart... e.PrintMessage(); jack_info("NetAdapter is restarted"); Reset(); fThread.DropSelfRealTime(); fThread.SetStatus(JackThread::kIniting); if (Init()) { fThread.SetStatus(JackThread::kRunning); return true; } else { return false; } } } //transport--------------------------------------------------------------------------- void JackNetAdapter::DecodeTransportData() { //TODO : we need here to get the actual timebase master to eventually release it from its duty (see JackNetDriver) //is there a new transport state ? if (fSendTransportData.fNewState &&(fSendTransportData.fState != jack_transport_query(fClient, NULL))) { switch (fSendTransportData.fState) { case JackTransportStopped : jack_transport_stop(fClient); jack_info("NetMaster : transport stops"); break; case JackTransportStarting : jack_transport_reposition(fClient, &fSendTransportData.fPosition); jack_transport_start(fClient); jack_info("NetMaster : transport starts"); break; case JackTransportRolling : // TODO, we need to : // - find a way to call TransportEngine->SetNetworkSync() // - turn the transport state to JackTransportRolling jack_info("NetMaster : transport rolls"); break; } } } void JackNetAdapter::EncodeTransportData() { //is there a timebase master change ? int refnum = -1; bool conditional = 0; //TODO : get the actual timebase master if (refnum != fLastTimebaseMaster) { //timebase master has released its function if (refnum == -1) { fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER; jack_info("Sending a timebase master release request."); } else { //there is a new timebase master fReturnTransportData.fTimebaseMaster = (conditional) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER; jack_info("Sending a %s timebase master request.", (conditional) ? "conditional" : "non-conditional"); } fLastTimebaseMaster = refnum; } else { fReturnTransportData.fTimebaseMaster = NO_CHANGE; } //update transport state and position fReturnTransportData.fState = jack_transport_query(fClient, &fReturnTransportData.fPosition); //is it a new state (that the master need to know...) ? fReturnTransportData.fNewState = ((fReturnTransportData.fState != fLastTransportState) && (fReturnTransportData.fState != fSendTransportData.fState)); if (fReturnTransportData.fNewState) { jack_info("Sending transport state '%s'.", GetTransportState(fReturnTransportData.fState)); } fLastTransportState = fReturnTransportData.fState; } //read/write operations--------------------------------------------------------------- int JackNetAdapter::Read() { switch (SyncRecv()) { case SOCKET_ERROR: return SOCKET_ERROR; case SYNC_PACKET_ERROR: // Since sync packet is incorrect, don't decode it and continue with data break; default: //decode sync int unused_frames; DecodeSyncPacket(unused_frames); break; } return DataRecv(); } int JackNetAdapter::Write() { EncodeSyncPacket(); if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; } return DataSend(); } //process----------------------------------------------------------------------------- int JackNetAdapter::Process() { //read data from the network //in case of fatal network error, stop the process if (Read() == SOCKET_ERROR) { return SOCKET_ERROR; } PushAndPull(fSoftCaptureBuffer, fSoftPlaybackBuffer, fAdaptedBufferSize); //then write data to network //in case of failure, stop process if (Write() == SOCKET_ERROR) { return SOCKET_ERROR; } return 0; } } // namespace Jack //loader------------------------------------------------------------------------------ #ifdef __cplusplus extern "C" { #endif #include "driver_interface.h" #include "JackAudioAdapter.h" using namespace Jack; SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("netadapter", JackDriverNone, "netjack net <==> audio backend adapter", &filler); strcpy(value.str, DEFAULT_MULTICAST_IP); jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address, or explicit IP of the master", NULL); value.i = DEFAULT_PORT; jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL); value.i = DEFAULT_MTU; jack_driver_descriptor_add_parameter(desc, &filler, "mtu", 'M', JackDriverParamInt, &value, NULL, "MTU to the master", NULL); value.i = 2; jack_driver_descriptor_add_parameter(desc, &filler, "input-ports", 'C', JackDriverParamInt, &value, NULL, "Number of audio input ports", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "output-ports", 'P', JackDriverParamInt, &value, NULL, "Number of audio output ports", NULL); #if HAVE_CELT value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamInt, &value, NULL, "Set CELT encoding and number of kBits per channel", NULL); #endif #if HAVE_OPUS value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'O', JackDriverParamInt, &value, NULL, "Set Opus encoding and number of kBits per channel", NULL); #endif strcpy(value.str, "'hostname'"); jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL); value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL); value.ui = 5U; jack_driver_descriptor_add_parameter(desc, &filler, "latency", 'l', JackDriverParamUInt, &value, NULL, "Network latency", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL); value.i = 32768; jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)"); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "auto-connect", 'c', JackDriverParamBool, &value, NULL, "Auto connect netadapter to system ports", NULL); return desc; } SERVER_EXPORT int jack_internal_initialize(jack_client_t* client, const JSList* params) { jack_log("Loading netadapter"); Jack::JackAudioAdapter* adapter; jack_nframes_t buffer_size = jack_get_buffer_size(client); jack_nframes_t sample_rate = jack_get_sample_rate(client); try { adapter = new Jack::JackAudioAdapter(client, new Jack::JackNetAdapter(client, buffer_size, sample_rate, params), params); assert(adapter); if (adapter->Open() == 0) { return 0; } else { delete adapter; return 1; } } catch (...) { jack_info("netadapter allocation error"); return 1; } } SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init) { JSList* params = NULL; bool parse_params = true; int res = 1; jack_driver_desc_t* desc = jack_get_descriptor(); Jack::JackArgParser parser(load_init); if (parser.GetArgc() > 0) { parse_params = parser.ParseParams(desc, ¶ms); } if (parse_params) { res = jack_internal_initialize(jack_client, params); parser.FreeParams(params); } return res; } SERVER_EXPORT void jack_finish(void* arg) { Jack::JackAudioAdapter* adapter = static_cast(arg); if (adapter) { jack_log("Unloading netadapter"); adapter->Close(); delete adapter; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/common/JackInternalSessionLoader.cpp0000644000000000000000000001400413214314510020373 0ustar rootroot/* Copyright (C) 2017 Timo Wischer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "JackInternalSessionLoader.h" #include "JackLockedEngine.h" namespace Jack { JackInternalSessionLoader::JackInternalSessionLoader(JackServer* const server) : fServer(server) { } int JackInternalSessionLoader::Load(const char* file) { std::ifstream infile(file); if (!infile.is_open()) { jack_error("JACK internal session file %s does not exist or cannot be opened for reading.", file); return -1; } std::string line; int linenr = -1; while (std::getline(infile, line)) { linenr++; std::istringstream iss(line); std::string command; if ( !(iss >> command) ) { /* ignoring empty line or line only filled with spaces */ continue; } /* convert command to lower case to accept any case of the letters in the command */ std::transform(command.begin(), command.end(), command.begin(), ::tolower); if ( (command.compare("c") == 0) || (command.compare("con") == 0) ) { ConnectPorts(iss, linenr); } else if ( (command.compare("l") == 0) || (command.compare("load") == 0) ) { LoadClient(iss, linenr); #if 0 /* NOTE: c++11 only */ } else if (command.front() == '#') { #else } else if (command[0] == '#') { #endif /* ignoring commented lines. * The # can be followed by non spaces. * Therefore only compare the first letter of the command. */ } else { jack_error("JACK internal session file %s line %u contains unkown command '%s'. Ignoring the line!", file, linenr, line.c_str()); } } return 0; } void JackInternalSessionLoader::LoadClient(std::istringstream& iss, const int linenr) { std::string client_name; if ( !(iss >> client_name) ) { jack_error("Cannot read client name from internal session file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str()); return; } std::string lib_name; if ( !(iss >> lib_name) ) { jack_error("Cannot read client library name from internal session file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str()); return; } /* get the rest of the line */ std::string parameters; if ( std::getline(iss, parameters) ) { /* remove the leading spaces */ const std::size_t start = parameters.find_first_not_of(" \t"); if (start == std::string::npos) { /* Parameters containing only spaces. * Use empty parameter string. */ parameters = ""; } else { parameters = parameters.substr(start); } } /* jackctl_server_load_internal() can not be used * because it calls jack_internal_initialize() * instead of jack_initialize() */ int status = 0; int refnum = 0; if (fServer->InternalClientLoad1(client_name.c_str(), lib_name.c_str(), parameters.c_str(), (JackLoadName|JackUseExactName|JackLoadInit), &refnum, -1, &status) < 0) { /* Due to the JackUseExactName option JackNameNotUnique will always handled as a failure. * See JackEngine::ClientCheck(). */ if (status & JackNameNotUnique) { jack_error("Internal client name `%s' not unique", client_name.c_str()); } /* An error message for JackVersionError will already * be printed by JackInternalClient::Open(). * Therefore no need to handle it here. */ jack_error("Cannot load client %s from internal session file line %u. Ignoring the line!", client_name.c_str(), linenr); return; } /* status has not to be checked for JackFailure * because JackServer::InternalClientLoad1() will return a value < 0 * and this is handled by the previouse if-clause. */ jack_info("Internal client %s successfully loaded", client_name.c_str()); } void JackInternalSessionLoader::ConnectPorts(std::istringstream& iss, const int linenr) { std::string src_port; if ( !(iss >> src_port) ) { jack_error("Cannot read first port from internal session file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str()); return; } std::string dst_port; if ( !(iss >> dst_port) ) { jack_error("Cannot read second port from internal session file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str()); return; } /* use the client reference of the source port */ const jack_port_id_t src_port_index = fServer->GetGraphManager()->GetPort(src_port.c_str()); if (src_port_index >= NO_PORT) { jack_error("Source port %s does not exist! Ignoring internal session file line %u '%s'.", src_port.c_str(), linenr, iss.str().c_str()); return; } const int src_refnum = fServer->GetGraphManager()->GetOutputRefNum(src_port_index); if (fServer->GetEngine()->PortConnect(src_refnum, src_port.c_str(), dst_port.c_str()) < 0) { jack_error("Cannot connect ports of internal session file line %u '%s'.\n" "Possibly the destination port does not exist. Ignoring the line!", linenr, iss.str().c_str()); return; } jack_info("Ports connected: %s -> %s", src_port.c_str(), dst_port.c_str()); } } 1.9.12~dfsg/common/JackRequest.h0000644000000000000000000013242413214314510015230 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackRequest__ #define __JackRequest__ #include "JackConstants.h" #include "JackError.h" #include "JackPlatformPlug.h" #include "JackChannel.h" #include "JackTime.h" #include "types.h" #include #include #include #include namespace Jack { #define CheckRes(exp) { if ((exp) < 0) { jack_error("CheckRes error"); return -1; } } #define CheckSize() { CheckRes(trans->Read(&fSize, sizeof(int))); if (fSize != Size()) { jack_error("CheckSize error size = %d Size() = %d", fSize, Size()); return -1; } } /*! \brief Session API constants. */ enum JackSessionReply { kImmediateSessionReply = 1, kPendingSessionReply = 2 }; /*! \brief Request from client to server. */ struct JackRequest { enum RequestType { kRegisterPort = 1, kUnRegisterPort = 2, kConnectPorts = 3, kDisconnectPorts = 4, kSetTimeBaseClient = 5, kActivateClient = 6, kDeactivateClient = 7, kDisconnectPort = 8, kSetClientCapabilities = 9, kGetPortConnections = 10, kGetPortNConnections = 11, kReleaseTimebase = 12, kSetTimebaseCallback = 13, kSetBufferSize = 20, kSetFreeWheel = 21, kClientCheck = 22, kClientOpen = 23, kClientClose = 24, kConnectNamePorts = 25, kDisconnectNamePorts = 26, kGetInternalClientName = 27, kInternalClientHandle = 28, kInternalClientLoad = 29, kInternalClientUnload = 30, kPortRename = 31, kNotification = 32, kSessionNotify = 33, kSessionReply = 34, kGetClientByUUID = 35, kReserveClientName = 36, kGetUUIDByClient = 37, kClientHasSessionCallback = 38, kComputeTotalLatencies = 39 }; RequestType fType; int fSize; JackRequest(): fType((RequestType)0), fSize(0) {} JackRequest(RequestType type): fType(type), fSize(0) {} virtual ~JackRequest() {} virtual int Read(detail::JackChannelTransactionInterface* trans) { return trans->Read(&fType, sizeof(RequestType)); } virtual int Write(detail::JackChannelTransactionInterface* trans) { return -1; } virtual int Write(detail::JackChannelTransactionInterface* trans, int size) { fSize = size; CheckRes(trans->Write(&fType, sizeof(RequestType))); return trans->Write(&fSize, sizeof(int)); } virtual int Size() { return 0; } }; /*! \brief Result from the server. */ struct JackResult { int fResult; JackResult(): fResult( -1) {} JackResult(int result): fResult(result) {} virtual ~JackResult() {} virtual int Read(detail::JackChannelTransactionInterface* trans) { return trans->Read(&fResult, sizeof(int)); } virtual int Write(detail::JackChannelTransactionInterface* trans) { return trans->Write(&fResult, sizeof(int)); } }; /*! \brief CheckClient request. */ struct JackClientCheckRequest : public JackRequest { char fName[JACK_CLIENT_NAME_SIZE+1]; int fProtocol; int fOptions; int fUUID; int fOpen; JackClientCheckRequest() : fProtocol(0), fOptions(0), fUUID(0), fOpen(0) { memset(fName, 0, sizeof(fName)); } JackClientCheckRequest(const char* name, int protocol, int options, int uuid, int open = false) : JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options), fUUID(uuid), fOpen(open) { memset(fName, 0, sizeof(fName)); snprintf(fName, sizeof(fName), "%s", name); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fProtocol, sizeof(int))); CheckRes(trans->Read(&fOptions, sizeof(int))); CheckRes(trans->Read(&fUUID, sizeof(int))); return trans->Read(&fOpen, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fProtocol, sizeof(int))); CheckRes(trans->Write(&fOptions, sizeof(int))); CheckRes(trans->Write(&fUUID, sizeof(int))); return trans->Write(&fOpen, sizeof(int)); } int Size() { return sizeof(fName) + 4 * sizeof(int); } }; /*! \brief CheckClient result. */ struct JackClientCheckResult : public JackResult { char fName[JACK_CLIENT_NAME_SIZE+1]; int fStatus; JackClientCheckResult(): JackResult(), fStatus(0) { memset(fName, 0, sizeof(fName)); } JackClientCheckResult(int32_t result, const char* name, int status) : JackResult(result), fStatus(status) { memset(fName, 0, sizeof(fName)); snprintf(fName, sizeof(fName), "%s", name); } int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fStatus, sizeof(int))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } }; /*! \brief NewClient request. */ struct JackClientOpenRequest : public JackRequest { int fPID; int fUUID; char fName[JACK_CLIENT_NAME_SIZE+1]; JackClientOpenRequest() : fPID(0), fUUID(0) { memset(fName, 0, sizeof(fName)); } JackClientOpenRequest(const char* name, int pid, int uuid): JackRequest(JackRequest::kClientOpen) { memset(fName, 0, sizeof(fName)); snprintf(fName, sizeof(fName), "%s", name); fPID = pid; fUUID = uuid; } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fPID, sizeof(int))); CheckRes(trans->Read(&fUUID, sizeof(int))); return trans->Read(&fName, sizeof(fName)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fPID, sizeof(int))); CheckRes(trans->Write(&fUUID, sizeof(int))); return trans->Write(&fName, sizeof(fName)); } int Size() { return 2 * sizeof(int) + sizeof(fName); } }; /*! \brief NewClient result. */ struct JackClientOpenResult : public JackResult { int fSharedEngine; int fSharedClient; int fSharedGraph; JackClientOpenResult() : JackResult(), fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1) {} JackClientOpenResult(int32_t result, int index1, int index2, int index3) : JackResult(result), fSharedEngine(index1), fSharedClient(index2), fSharedGraph(index3) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); CheckRes(trans->Read(&fSharedEngine, sizeof(int))); CheckRes(trans->Read(&fSharedClient, sizeof(int))); CheckRes(trans->Read(&fSharedGraph, sizeof(int))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); CheckRes(trans->Write(&fSharedEngine, sizeof(int))); CheckRes(trans->Write(&fSharedClient, sizeof(int))); CheckRes(trans->Write(&fSharedGraph, sizeof(int))); return 0; } }; /*! \brief CloseClient request. */ struct JackClientCloseRequest : public JackRequest { int fRefNum; JackClientCloseRequest() : fRefNum(0) {} JackClientCloseRequest(int refnum): JackRequest(JackRequest::kClientClose), fRefNum(refnum) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); return trans->Read(&fRefNum, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); return trans->Write(&fRefNum, sizeof(int)); } int Size() { return sizeof(int); } }; /*! \brief Activate request. */ struct JackActivateRequest : public JackRequest { int fRefNum; int fIsRealTime; JackActivateRequest() : fRefNum(0), fIsRealTime(0) {} JackActivateRequest(int refnum, int is_real_time) : JackRequest(JackRequest::kActivateClient), fRefNum(refnum), fIsRealTime(is_real_time) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); return trans->Read(&fIsRealTime, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fIsRealTime, sizeof(int)); } int Size() { return 2 * sizeof(int); } }; /*! \brief Deactivate request. */ struct JackDeactivateRequest : public JackRequest { int fRefNum; JackDeactivateRequest() : fRefNum(0) {} JackDeactivateRequest(int refnum): JackRequest(JackRequest::kDeactivateClient), fRefNum(refnum) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); return trans->Read(&fRefNum, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); return trans->Write(&fRefNum, sizeof(int)); } int Size() { return sizeof(int); } }; /*! \brief PortRegister request. */ struct JackPortRegisterRequest : public JackRequest { int fRefNum; char fName[JACK_PORT_NAME_SIZE + 1]; // port short name char fPortType[JACK_PORT_TYPE_SIZE + 1]; unsigned int fFlags; unsigned int fBufferSize; JackPortRegisterRequest() : fRefNum(0), fFlags(0), fBufferSize(0) { memset(fName, 0, sizeof(fName)); memset(fPortType, 0, sizeof(fPortType)); } JackPortRegisterRequest(int refnum, const char* name, const char* port_type, unsigned int flags, unsigned int buffer_size) : JackRequest(JackRequest::kRegisterPort), fRefNum(refnum), fFlags(flags), fBufferSize(buffer_size) { memset(fName, 0, sizeof(fName)); memset(fPortType, 0, sizeof(fPortType)); strncpy(fName, name, sizeof(fName)-1); strncpy(fPortType, port_type, sizeof(fPortType)-1); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fPortType, sizeof(fPortType))); CheckRes(trans->Read(&fFlags, sizeof(unsigned int))); CheckRes(trans->Read(&fBufferSize, sizeof(unsigned int))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fPortType, sizeof(fPortType))); CheckRes(trans->Write(&fFlags, sizeof(unsigned int))); CheckRes(trans->Write(&fBufferSize, sizeof(unsigned int))); return 0; } int Size() { return sizeof(int) + sizeof(fName) + sizeof(fPortType) + 2 * sizeof(unsigned int); } }; /*! \brief PortRegister result. */ struct JackPortRegisterResult : public JackResult { jack_port_id_t fPortIndex; JackPortRegisterResult(): JackResult(), fPortIndex(NO_PORT) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); return trans->Read(&fPortIndex, sizeof(jack_port_id_t)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); return trans->Write(&fPortIndex, sizeof(jack_port_id_t)); } }; /*! \brief PortUnregister request. */ struct JackPortUnRegisterRequest : public JackRequest { int fRefNum; jack_port_id_t fPortIndex; JackPortUnRegisterRequest() : fRefNum(0), fPortIndex(0) {} JackPortUnRegisterRequest(int refnum, jack_port_id_t index) : JackRequest(JackRequest::kUnRegisterPort), fRefNum(refnum), fPortIndex(index) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fPortIndex, sizeof(jack_port_id_t))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fPortIndex, sizeof(jack_port_id_t))); return 0; } int Size() { return sizeof(int) + sizeof(jack_port_id_t); } }; /*! \brief PortConnectName request. */ struct JackPortConnectNameRequest : public JackRequest { int fRefNum; char fSrc[REAL_JACK_PORT_NAME_SIZE+1]; // port full name char fDst[REAL_JACK_PORT_NAME_SIZE+1]; // port full name JackPortConnectNameRequest() : fRefNum(0) { memset(fSrc, 0, sizeof(fSrc)); memset(fDst, 0, sizeof(fDst)); } JackPortConnectNameRequest(int refnum, const char* src_name, const char* dst_name) : JackRequest(JackRequest::kConnectNamePorts), fRefNum(refnum) { memset(fSrc, 0, sizeof(fSrc)); memset(fDst, 0, sizeof(fDst)); strncpy(fSrc, src_name, sizeof(fSrc)-1); strncpy(fDst, dst_name, sizeof(fDst)-1); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fSrc, sizeof(fSrc))); CheckRes(trans->Read(&fDst, sizeof(fDst))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fSrc, sizeof(fSrc))); CheckRes(trans->Write(&fDst, sizeof(fDst))); return 0; } int Size() { return sizeof(int) + sizeof(fSrc) + sizeof(fDst); } }; /*! \brief PortDisconnectName request. */ struct JackPortDisconnectNameRequest : public JackRequest { int fRefNum; char fSrc[REAL_JACK_PORT_NAME_SIZE+1]; // port full name char fDst[REAL_JACK_PORT_NAME_SIZE+1]; // port full name JackPortDisconnectNameRequest() : fRefNum(0) { memset(fSrc, 0, sizeof(fSrc)); memset(fDst, 0, sizeof(fDst)); } JackPortDisconnectNameRequest(int refnum, const char* src_name, const char* dst_name) : JackRequest(JackRequest::kDisconnectNamePorts), fRefNum(refnum) { memset(fSrc, 0, sizeof(fSrc)); memset(fDst, 0, sizeof(fDst)); strncpy(fSrc, src_name, sizeof(fSrc)-1); strncpy(fDst, dst_name, sizeof(fDst)-1); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fSrc, sizeof(fSrc))); CheckRes(trans->Read(&fDst, sizeof(fDst))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fSrc, sizeof(fSrc))); CheckRes(trans->Write(&fDst, sizeof(fDst))); return 0; } int Size() { return sizeof(int) + sizeof(fSrc) + sizeof(fDst); } }; /*! \brief PortConnect request. */ struct JackPortConnectRequest : public JackRequest { int fRefNum; jack_port_id_t fSrc; jack_port_id_t fDst; JackPortConnectRequest() : fRefNum(0), fSrc(0), fDst(0) {} JackPortConnectRequest(int refnum, jack_port_id_t src, jack_port_id_t dst) : JackRequest(JackRequest::kConnectPorts), fRefNum(refnum), fSrc(src), fDst(dst) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fSrc, sizeof(jack_port_id_t))); CheckRes(trans->Read(&fDst, sizeof(jack_port_id_t))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fSrc, sizeof(jack_port_id_t))); CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t))); return 0; } int Size() { return sizeof(int) + sizeof(jack_port_id_t) + sizeof(jack_port_id_t); } }; /*! \brief PortDisconnect request. */ struct JackPortDisconnectRequest : public JackRequest { int fRefNum; jack_port_id_t fSrc; jack_port_id_t fDst; JackPortDisconnectRequest() : fRefNum(0), fSrc(0), fDst(0) {} JackPortDisconnectRequest(int refnum, jack_port_id_t src, jack_port_id_t dst) : JackRequest(JackRequest::kDisconnectPorts), fRefNum(refnum), fSrc(src), fDst(dst) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fSrc, sizeof(jack_port_id_t))); CheckRes(trans->Read(&fDst, sizeof(jack_port_id_t))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fSrc, sizeof(jack_port_id_t))); CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t))); return 0; } int Size() { return sizeof(int) + sizeof(jack_port_id_t) + sizeof(jack_port_id_t); } }; /*! \brief PortRename request. */ struct JackPortRenameRequest : public JackRequest { int fRefNum; jack_port_id_t fPort; char fName[JACK_PORT_NAME_SIZE + 1]; // port short name JackPortRenameRequest() : fRefNum(0), fPort(0) { memset(fName, 0, sizeof(fName)); } JackPortRenameRequest(int refnum, jack_port_id_t port, const char* name) : JackRequest(JackRequest::kPortRename), fRefNum(refnum), fPort(port) { memset(fName, 0, sizeof(fName)); strncpy(fName, name, sizeof(fName)-1); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fPort, sizeof(jack_port_id_t))); CheckRes(trans->Read(&fName, sizeof(fName))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fPort, sizeof(jack_port_id_t))); CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } int Size() { return sizeof(int) + sizeof(jack_port_id_t) + sizeof(fName); } }; /*! \brief SetBufferSize request. */ struct JackSetBufferSizeRequest : public JackRequest { jack_nframes_t fBufferSize; JackSetBufferSizeRequest() : fBufferSize(0) {} JackSetBufferSizeRequest(jack_nframes_t buffer_size) : JackRequest(JackRequest::kSetBufferSize), fBufferSize(buffer_size) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); return trans->Read(&fBufferSize, sizeof(jack_nframes_t)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); return trans->Write(&fBufferSize, sizeof(jack_nframes_t)); } int Size() { return sizeof(jack_nframes_t); } }; /*! \brief SetFreeWheel request. */ struct JackSetFreeWheelRequest : public JackRequest { int fOnOff; JackSetFreeWheelRequest() : fOnOff(0) {} JackSetFreeWheelRequest(int onoff) : JackRequest(JackRequest::kSetFreeWheel), fOnOff(onoff) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); return trans->Read(&fOnOff, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); return trans->Write(&fOnOff, sizeof(int)); } int Size() { return sizeof(int); } }; /*! \brief ComputeTotalLatencies request. */ struct JackComputeTotalLatenciesRequest : public JackRequest { JackComputeTotalLatenciesRequest() : JackRequest(JackRequest::kComputeTotalLatencies) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); return 0; } int Size() { return 0; } }; /*! \brief ReleaseTimebase request. */ struct JackReleaseTimebaseRequest : public JackRequest { int fRefNum; JackReleaseTimebaseRequest() : fRefNum(0) {} JackReleaseTimebaseRequest(int refnum) : JackRequest(JackRequest::kReleaseTimebase), fRefNum(refnum) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); return trans->Read(&fRefNum, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); return trans->Write(&fRefNum, sizeof(int)); } int Size() { return sizeof(int); } }; /*! \brief SetTimebaseCallback request. */ struct JackSetTimebaseCallbackRequest : public JackRequest { int fRefNum; int fConditionnal; JackSetTimebaseCallbackRequest() : fRefNum(0), fConditionnal(0) {} JackSetTimebaseCallbackRequest(int refnum, int conditional) : JackRequest(JackRequest::kSetTimebaseCallback), fRefNum(refnum), fConditionnal(conditional) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); return trans->Read(&fConditionnal, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fConditionnal, sizeof(int)); } int Size() { return sizeof(int) + sizeof(int); } }; /*! \brief GetInternalClientName request. */ struct JackGetInternalClientNameRequest : public JackRequest { int fRefNum; int fIntRefNum; JackGetInternalClientNameRequest() : fRefNum(0), fIntRefNum(0) {} JackGetInternalClientNameRequest(int refnum, int int_ref) : JackRequest(JackRequest::kGetInternalClientName), fRefNum(refnum), fIntRefNum(int_ref) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); return trans->Read(&fIntRefNum, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fIntRefNum, sizeof(int)); } int Size() { return sizeof(int) + sizeof(int); } }; /*! \brief GetInternalClient result. */ struct JackGetInternalClientNameResult : public JackResult { char fName[JACK_CLIENT_NAME_SIZE+1]; JackGetInternalClientNameResult(): JackResult() { memset(fName, 0, sizeof(fName)); } JackGetInternalClientNameResult(int32_t result, const char* name) : JackResult(result) { memset(fName, 0, sizeof(fName)); snprintf(fName, sizeof(fName), "%s", name); } int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); CheckRes(trans->Read(&fName, sizeof(fName))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } int Size() { return sizeof(fName); } }; /*! \brief InternalClientHandle request. */ struct JackInternalClientHandleRequest : public JackRequest { int fRefNum; char fName[JACK_CLIENT_NAME_SIZE+1]; JackInternalClientHandleRequest() : fRefNum(0) { memset(fName, 0, sizeof(fName)); } JackInternalClientHandleRequest(int refnum, const char* client_name) : JackRequest(JackRequest::kInternalClientHandle), fRefNum(refnum) { memset(fName, 0, sizeof(fName)); snprintf(fName, sizeof(fName), "%s", client_name); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); return trans->Read(&fName, sizeof(fName)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fName, sizeof(fName)); } int Size() { return sizeof(int) + sizeof(fName); } }; /*! \brief InternalClientHandle result. */ struct JackInternalClientHandleResult : public JackResult { int fStatus; int fIntRefNum; JackInternalClientHandleResult(): JackResult(), fStatus(0), fIntRefNum(0) {} JackInternalClientHandleResult(int32_t result, int status, int int_ref) : JackResult(result), fStatus(status), fIntRefNum(int_ref) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); CheckRes(trans->Read(&fStatus, sizeof(int))); CheckRes(trans->Read(&fIntRefNum, sizeof(int))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); CheckRes(trans->Write(&fStatus, sizeof(int))); CheckRes(trans->Write(&fIntRefNum, sizeof(int))); return 0; } int Size() { return sizeof(int) + sizeof(int); } }; /*! \brief InternalClientLoad request. */ struct JackInternalClientLoadRequest : public JackRequest { #ifndef MAX_PATH #define MAX_PATH 256 #endif int fRefNum; char fName[JACK_CLIENT_NAME_SIZE+1]; char fDllName[MAX_PATH+1]; char fLoadInitName[JACK_LOAD_INIT_LIMIT+1]; int fOptions; int fUUID; JackInternalClientLoadRequest() : fRefNum(0), fOptions(0), fUUID(0) { memset(fName, 0, sizeof(fName)); memset(fDllName, 0, sizeof(fDllName)); memset(fLoadInitName, 0, sizeof(fLoadInitName)); } JackInternalClientLoadRequest(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int uuid ) : JackRequest(JackRequest::kInternalClientLoad), fRefNum(refnum), fOptions(options), fUUID(uuid) { memset(fName, 0, sizeof(fName)); memset(fDllName, 0, sizeof(fDllName)); memset(fLoadInitName, 0, sizeof(fLoadInitName)); snprintf(fName, sizeof(fName), "%s", client_name); snprintf(fDllName, sizeof(fDllName), "%s", so_name); snprintf(fLoadInitName, sizeof(fLoadInitName), "%s", objet_data); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fDllName, sizeof(fDllName))); CheckRes(trans->Read(&fLoadInitName, sizeof(fLoadInitName))); CheckRes(trans->Read(&fUUID, sizeof(int))); return trans->Read(&fOptions, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fDllName, sizeof(fDllName))); CheckRes(trans->Write(&fLoadInitName, sizeof(fLoadInitName))); CheckRes(trans->Write(&fUUID, sizeof(int))); return trans->Write(&fOptions, sizeof(int)); } int Size() { return sizeof(int) + sizeof(fName) + sizeof(fDllName) + sizeof(fLoadInitName) + 2 * sizeof(int); } }; /*! \brief InternalClientLoad result. */ struct JackInternalClientLoadResult : public JackResult { int fStatus; int fIntRefNum; JackInternalClientLoadResult(): JackResult(), fStatus(0), fIntRefNum(0) {} JackInternalClientLoadResult(int32_t result, int status, int int_ref) : JackResult(result), fStatus(status), fIntRefNum(int_ref) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); CheckRes(trans->Read(&fStatus, sizeof(int))); CheckRes(trans->Read(&fIntRefNum, sizeof(int))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); CheckRes(trans->Write(&fStatus, sizeof(int))); CheckRes(trans->Write(&fIntRefNum, sizeof(int))); return 0; } int Size() { return sizeof(int) + sizeof(int); } }; /*! \brief InternalClientUnload request. */ struct JackInternalClientUnloadRequest : public JackRequest { int fRefNum; int fIntRefNum; JackInternalClientUnloadRequest() : fRefNum(0), fIntRefNum(0) {} JackInternalClientUnloadRequest(int refnum, int int_ref) : JackRequest(JackRequest::kInternalClientUnload), fRefNum(refnum), fIntRefNum(int_ref) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); return trans->Read(&fIntRefNum, sizeof(int)); } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fIntRefNum, sizeof(int)); } int Size() { return sizeof(int) + sizeof(int); } }; /*! \brief InternalClientLoad result. */ struct JackInternalClientUnloadResult : public JackResult { int fStatus; JackInternalClientUnloadResult(): JackResult(), fStatus(0) {} JackInternalClientUnloadResult(int32_t result, int status) : JackResult(result), fStatus(status) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); CheckRes(trans->Read(&fStatus, sizeof(int))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } int Size() { return sizeof(int); } }; /*! \brief ClientNotification request. */ struct JackClientNotificationRequest : public JackRequest { int fRefNum; int fNotify; int fValue; JackClientNotificationRequest() : fRefNum(0), fNotify(0), fValue(0) {} JackClientNotificationRequest(int refnum, int notify, int value) : JackRequest(JackRequest::kNotification), fRefNum(refnum), fNotify(notify), fValue(value) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fNotify, sizeof(int))); CheckRes(trans->Read(&fValue, sizeof(int))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fNotify, sizeof(int))); CheckRes(trans->Write(&fValue, sizeof(int))); return 0; } int Size() { return 3 * sizeof(int); } }; struct JackSessionCommand { char fUUID[JACK_UUID_SIZE]; char fClientName[JACK_CLIENT_NAME_SIZE+1]; char fCommand[JACK_SESSION_COMMAND_SIZE]; jack_session_flags_t fFlags; JackSessionCommand() : fFlags(JackSessionSaveError) { memset(fUUID, 0, sizeof(fUUID)); memset(fClientName, 0, sizeof(fClientName)); memset(fCommand, 0, sizeof(fCommand)); } JackSessionCommand(const char *uuid, const char *clientname, const char *command, jack_session_flags_t flags) { memset(fUUID, 0, sizeof(fUUID)); memset(fClientName, 0, sizeof(fClientName)); memset(fCommand, 0, sizeof(fCommand)); strncpy(fUUID, uuid, sizeof(fUUID)-1); strncpy(fClientName, clientname, sizeof(fClientName)-1); strncpy(fCommand, command, sizeof(fCommand)-1); fFlags = flags; } }; struct JackSessionNotifyResult : public JackResult { std::list fCommandList; bool fDone; JackSessionNotifyResult(): JackResult(), fDone(false) {} JackSessionNotifyResult(int32_t result) : JackResult(result), fDone(false) {} int Read(detail::JackChannelTransactionInterface* trans) { if (trans == NULL) { return 0; } CheckRes(JackResult::Read(trans)); while (true) { JackSessionCommand buffer; CheckRes(trans->Read(buffer.fUUID, sizeof(buffer.fUUID))); if (buffer.fUUID[0] == '\0') break; CheckRes(trans->Read(buffer.fClientName, sizeof(buffer.fClientName))); CheckRes(trans->Read(buffer.fCommand, sizeof(buffer.fCommand))); CheckRes(trans->Read(&(buffer.fFlags), sizeof(buffer.fFlags))); fCommandList.push_back(buffer); } fDone = true; return 0; } int Write(detail::JackChannelTransactionInterface* trans) { if (trans == NULL) { fDone = true; return 0; } char terminator[JACK_UUID_SIZE]; terminator[0] = '\0'; CheckRes(JackResult::Write(trans)); for (std::list::iterator i = fCommandList.begin(); i != fCommandList.end(); i++) { CheckRes(trans->Write(i->fUUID, sizeof(i->fUUID))); CheckRes(trans->Write(i->fClientName, sizeof(i->fClientName))); CheckRes(trans->Write(i->fCommand, sizeof(i->fCommand))); CheckRes(trans->Write(&(i->fFlags), sizeof(i->fFlags))); } CheckRes(trans->Write(terminator, sizeof(terminator))); return 0; } jack_session_command_t* GetCommands() { /* TODO: some kind of signal should be used instead */ while (!fDone) { JackSleep(50000); /* 50 ms */ } jack_session_command_t* session_command = (jack_session_command_t *)malloc(sizeof(jack_session_command_t) * (fCommandList.size() + 1)); int i = 0; for (std::list::iterator ci = fCommandList.begin(); ci != fCommandList.end(); ci++) { session_command[i].uuid = strdup(ci->fUUID); session_command[i].client_name = strdup(ci->fClientName); session_command[i].command = strdup(ci->fCommand); session_command[i].flags = ci->fFlags; i += 1; } session_command[i].uuid = NULL; session_command[i].client_name = NULL; session_command[i].command = NULL; session_command[i].flags = (jack_session_flags_t)0; return session_command; } }; /*! \brief SessionNotify request. */ struct JackSessionNotifyRequest : public JackRequest { char fPath[JACK_MESSAGE_SIZE+1]; char fDst[JACK_CLIENT_NAME_SIZE+1]; jack_session_event_type_t fEventType; int fRefNum; JackSessionNotifyRequest() : fEventType(JackSessionSave), fRefNum(0) {} JackSessionNotifyRequest(int refnum, const char* path, jack_session_event_type_t type, const char* dst) : JackRequest(JackRequest::kSessionNotify), fEventType(type), fRefNum(refnum) { memset(fPath, 0, sizeof(fPath)); memset(fDst, 0, sizeof(fDst)); snprintf(fPath, sizeof(fPath), "%s", path); fPath[JACK_MESSAGE_SIZE] = 0; if (dst) { snprintf(fDst, sizeof(fDst), "%s", dst); fDst[JACK_CLIENT_NAME_SIZE] = 0; } } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(fRefNum))); CheckRes(trans->Read(&fPath, sizeof(fPath))); CheckRes(trans->Read(&fDst, sizeof(fDst))); CheckRes(trans->Read(&fEventType, sizeof(fEventType))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(fRefNum))); CheckRes(trans->Write(&fPath, sizeof(fPath))); CheckRes(trans->Write(&fDst, sizeof(fDst))); CheckRes(trans->Write(&fEventType, sizeof(fEventType))); return 0; } int Size() { return sizeof(fRefNum) + sizeof(fPath) + sizeof(fDst) + sizeof(fEventType); } }; struct JackSessionReplyRequest : public JackRequest { int fRefNum; JackSessionReplyRequest() : fRefNum(0) {} JackSessionReplyRequest(int refnum) : JackRequest(JackRequest::kSessionReply), fRefNum(refnum) {} int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fRefNum, sizeof(int))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fRefNum, sizeof(int))); return 0; } int Size() { return sizeof(int); } }; struct JackClientNameResult : public JackResult { char fName[JACK_CLIENT_NAME_SIZE+1]; JackClientNameResult(): JackResult() { memset(fName, 0, sizeof(fName)); } JackClientNameResult(int32_t result, const char* name) : JackResult(result) { memset(fName, 0, sizeof(fName)); snprintf(fName, sizeof(fName), "%s", name); } int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); CheckRes(trans->Read(&fName, sizeof(fName))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } }; struct JackUUIDResult : public JackResult { char fUUID[JACK_UUID_SIZE]; JackUUIDResult(): JackResult() { memset(fUUID, 0, sizeof(fUUID)); } JackUUIDResult(int32_t result, const char* uuid) : JackResult(result) { memset(fUUID, 0, sizeof(fUUID)); snprintf(fUUID, sizeof(fUUID), "%s", uuid); } int Read(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Read(trans)); CheckRes(trans->Read(&fUUID, sizeof(fUUID))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackResult::Write(trans)); CheckRes(trans->Write(&fUUID, sizeof(fUUID))); return 0; } }; struct JackGetUUIDRequest : public JackRequest { char fName[JACK_CLIENT_NAME_SIZE+1]; JackGetUUIDRequest() { memset(fName, 0, sizeof(fName)); } JackGetUUIDRequest(const char* client_name) : JackRequest(JackRequest::kGetUUIDByClient) { memset(fName, 0, sizeof(fName)); strncpy(fName, client_name, sizeof(fName)-1); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fName, sizeof(fName))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } int Size() { return sizeof(fName); } }; struct JackGetClientNameRequest : public JackRequest { char fUUID[JACK_UUID_SIZE]; JackGetClientNameRequest() { memset(fUUID, 0, sizeof(fUUID)); } JackGetClientNameRequest(const char* uuid) : JackRequest(JackRequest::kGetClientByUUID) { memset(fUUID, 0, sizeof(fUUID)); strncpy(fUUID, uuid, sizeof(fUUID)-1); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fUUID, sizeof(fUUID))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fUUID, sizeof(fUUID))); return 0; } int Size() { return sizeof(fUUID); } }; struct JackReserveNameRequest : public JackRequest { int fRefNum; char fName[JACK_CLIENT_NAME_SIZE+1]; char fUUID[JACK_UUID_SIZE]; JackReserveNameRequest() : fRefNum(0) { memset(fName, 0, sizeof(fName)); memset(fUUID, 0, sizeof(fUUID)); } JackReserveNameRequest(int refnum, const char *name, const char* uuid) : JackRequest(JackRequest::kReserveClientName), fRefNum(refnum) { memset(fName, 0, sizeof(fName)); memset(fUUID, 0, sizeof(fUUID)); strncpy(fName, name, sizeof(fName)-1); strncpy(fUUID, uuid, sizeof(fUUID)-1); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fUUID, sizeof(fUUID))); CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fRefNum, sizeof(fRefNum))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fUUID, sizeof(fUUID))); CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fRefNum, sizeof(fRefNum))); return 0; } int Size() { return sizeof(fUUID) + sizeof(fName) + sizeof(fRefNum); } }; struct JackClientHasSessionCallbackRequest : public JackRequest { char fName[JACK_CLIENT_NAME_SIZE+1]; JackClientHasSessionCallbackRequest() { memset(fName, 0, sizeof(fName)); } JackClientHasSessionCallbackRequest(const char *name) : JackRequest(JackRequest::kClientHasSessionCallback) { memset(fName, 0, sizeof(fName)); strncpy(fName, name, sizeof(fName)-1); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fName, sizeof(fName))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(JackRequest::Write(trans, Size())); CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } int Size() { return sizeof(fName); } }; /*! \brief ClientNotification. */ struct JackClientNotification { int fSize; char fName[JACK_CLIENT_NAME_SIZE+1]; int fRefNum; int fNotify; int fValue1; int fValue2; int fSync; char fMessage[JACK_MESSAGE_SIZE+1]; JackClientNotification(): fSize(0), fRefNum(0), fNotify(-1), fValue1(-1), fValue2(-1), fSync(0) { memset(fName, 0, sizeof(fName)); memset(fMessage, 0, sizeof(fMessage)); } JackClientNotification(const char* name, int refnum, int notify, int sync, const char* message, int value1, int value2) : fRefNum(refnum), fNotify(notify), fValue1(value1), fValue2(value2), fSync(sync) { memset(fName, 0, sizeof(fName)); memset(fMessage, 0, sizeof(fMessage)); snprintf(fName, sizeof(fName), "%s", name); snprintf(fMessage, sizeof(fMessage), "%s", message); fSize = Size(); } int Read(detail::JackChannelTransactionInterface* trans) { CheckSize(); CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fNotify, sizeof(int))); CheckRes(trans->Read(&fValue1, sizeof(int))); CheckRes(trans->Read(&fValue2, sizeof(int))); CheckRes(trans->Read(&fSync, sizeof(int))); CheckRes(trans->Read(&fMessage, sizeof(fMessage))); return 0; } int Write(detail::JackChannelTransactionInterface* trans) { CheckRes(trans->Write(&fSize, sizeof(int))); CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fNotify, sizeof(int))); CheckRes(trans->Write(&fValue1, sizeof(int))); CheckRes(trans->Write(&fValue2, sizeof(int))); CheckRes(trans->Write(&fSync, sizeof(int))); CheckRes(trans->Write(&fMessage, sizeof(fMessage))); return 0; } int Size() { return sizeof(int) + sizeof(fName) + 5 * sizeof(int) + sizeof(fMessage); } }; } // end of namespace #endif 1.9.12~dfsg/common/JackDummyDriver.cpp0000644000000000000000000001026313214314510016376 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackDummyDriver.h" #include "JackDriverLoader.h" #include "JackThreadedDriver.h" #include "JackCompilerDeps.h" #include #include #include #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("dummy", JackDriverMaster, "Timer based backend", &filler); value.ui = 2U; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamUInt, &value, NULL, "Number of capture ports", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamUInt, &value, NULL, "Number of playback ports", NULL); value.ui = 48000U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "monitor", 'm', JackDriverParamBool, &value, NULL, "Provide monitor ports for the output", NULL); value.ui = 1024U; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = 21333U; jack_driver_descriptor_add_parameter(desc, &filler, "wait", 'w', JackDriverParamUInt, &value, NULL, "Number of usecs to wait between engine processes", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t sample_rate = 48000; jack_nframes_t buffer_size = 1024; unsigned int capture_ports = 2; unsigned int playback_ports = 2; int wait_time = 0; const JSList * node; const jack_driver_param_t * param; bool monitor = false; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'C': capture_ports = param->value.ui; break; case 'P': playback_ports = param->value.ui; break; case 'r': sample_rate = param->value.ui; break; case 'p': buffer_size = param->value.ui; break; case 'w': wait_time = param->value.ui; break; case 'm': monitor = param->value.i; break; } } if (wait_time > 0) { buffer_size = lroundf((float(wait_time) * float(sample_rate)) / 1000000.0f); } if (buffer_size > BUFFER_SIZE_MAX) { buffer_size = BUFFER_SIZE_MAX; jack_error("Buffer size set to %d", BUFFER_SIZE_MAX); } Jack::JackDriverClientInterface* driver = new Jack::JackThreadedDriver(new Jack::JackDummyDriver("system", "dummy_pcm", engine, table)); if (driver->Open(buffer_size, sample_rate, 1, 1, capture_ports, playback_ports, monitor, "dummy", "dummy", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/common/ringbuffer.c0000644000000000000000000002307213214314510015131 0ustar rootroot/* Copyright (C) 2000 Paul Davis Copyright (C) 2003 Rohan Drape This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ISO/POSIX C version of Paul Davis's lock free ringbuffer C++ code. This is safe for the case of one read thread and one write thread. */ #include #include #ifdef USE_MLOCK #include #endif /* USE_MLOCK */ #include "JackCompilerDeps.h" typedef struct { char *buf; size_t len; } jack_ringbuffer_data_t ; typedef struct { char *buf; volatile size_t write_ptr; volatile size_t read_ptr; size_t size; size_t size_mask; int mlocked; } jack_ringbuffer_t ; LIB_EXPORT jack_ringbuffer_t *jack_ringbuffer_create(size_t sz); LIB_EXPORT void jack_ringbuffer_free(jack_ringbuffer_t *rb); LIB_EXPORT void jack_ringbuffer_get_read_vector(const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *vec); LIB_EXPORT void jack_ringbuffer_get_write_vector(const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *vec); LIB_EXPORT size_t jack_ringbuffer_read(jack_ringbuffer_t *rb, char *dest, size_t cnt); LIB_EXPORT size_t jack_ringbuffer_peek(jack_ringbuffer_t *rb, char *dest, size_t cnt); LIB_EXPORT void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt); LIB_EXPORT size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb); LIB_EXPORT int jack_ringbuffer_mlock(jack_ringbuffer_t *rb); LIB_EXPORT void jack_ringbuffer_reset(jack_ringbuffer_t *rb); LIB_EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz); LIB_EXPORT size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src, size_t cnt); void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt); size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); /* Create a new ringbuffer to hold at least `sz' bytes of data. The actual buffer size is rounded up to the next power of two. */ LIB_EXPORT jack_ringbuffer_t * jack_ringbuffer_create (size_t sz) { int power_of_two; jack_ringbuffer_t *rb; if ((rb = (jack_ringbuffer_t *) malloc (sizeof (jack_ringbuffer_t))) == NULL) { return NULL; } for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); rb->size = 1 << power_of_two; rb->size_mask = rb->size; rb->size_mask -= 1; rb->write_ptr = 0; rb->read_ptr = 0; if ((rb->buf = (char *) malloc (rb->size)) == NULL) { free (rb); return NULL; } rb->mlocked = 0; return rb; } /* Free all data associated with the ringbuffer `rb'. */ LIB_EXPORT void jack_ringbuffer_free (jack_ringbuffer_t * rb) { #ifdef USE_MLOCK if (rb->mlocked) { munlock (rb->buf, rb->size); } #endif /* USE_MLOCK */ free (rb->buf); free (rb); } /* Lock the data block of `rb' using the system call 'mlock'. */ LIB_EXPORT int jack_ringbuffer_mlock (jack_ringbuffer_t * rb) { #ifdef USE_MLOCK if (mlock (rb->buf, rb->size)) { return -1; } #endif /* USE_MLOCK */ rb->mlocked = 1; return 0; } /* Reset the read and write pointers to zero. This is not thread safe. */ LIB_EXPORT void jack_ringbuffer_reset (jack_ringbuffer_t * rb) { rb->read_ptr = 0; rb->write_ptr = 0; memset(rb->buf, 0, rb->size); } /* Reset the read and write pointers to zero. This is not thread safe. */ LIB_EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz) { rb->size = sz; rb->size_mask = rb->size; rb->size_mask -= 1; rb->read_ptr = 0; rb->write_ptr = 0; } /* Return the number of bytes available for reading. This is the number of bytes in front of the read pointer and behind the write pointer. */ LIB_EXPORT size_t jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) { size_t w, r; w = rb->write_ptr; r = rb->read_ptr; if (w > r) { return w - r; } else { return (w - r + rb->size) & rb->size_mask; } } /* Return the number of bytes available for writing. This is the number of bytes in front of the write pointer and behind the read pointer. */ LIB_EXPORT size_t jack_ringbuffer_write_space (const jack_ringbuffer_t * rb) { size_t w, r; w = rb->write_ptr; r = rb->read_ptr; if (w > r) { return ((r - w + rb->size) & rb->size_mask) - 1; } else if (w < r) { return (r - w) - 1; } else { return rb->size - 1; } } /* The copying data reader. Copy at most `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes copied. */ LIB_EXPORT size_t jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt) { size_t free_cnt; size_t cnt2; size_t to_read; size_t n1, n2; if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { return 0; } to_read = cnt > free_cnt ? free_cnt : cnt; cnt2 = rb->read_ptr + to_read; if (cnt2 > rb->size) { n1 = rb->size - rb->read_ptr; n2 = cnt2 & rb->size_mask; } else { n1 = to_read; n2 = 0; } memcpy (dest, &(rb->buf[rb->read_ptr]), n1); rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; if (n2) { memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; } return to_read; } /* The copying data reader w/o read pointer advance. Copy at most `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes copied. */ LIB_EXPORT size_t jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt) { size_t free_cnt; size_t cnt2; size_t to_read; size_t n1, n2; size_t tmp_read_ptr; tmp_read_ptr = rb->read_ptr; if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { return 0; } to_read = cnt > free_cnt ? free_cnt : cnt; cnt2 = tmp_read_ptr + to_read; if (cnt2 > rb->size) { n1 = rb->size - tmp_read_ptr; n2 = cnt2 & rb->size_mask; } else { n1 = to_read; n2 = 0; } memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; if (n2) { memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); } return to_read; } /* The copying data writer. Copy at most `cnt' bytes to `rb' from `src'. Returns the actual number of bytes copied. */ LIB_EXPORT size_t jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt) { size_t free_cnt; size_t cnt2; size_t to_write; size_t n1, n2; if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { return 0; } to_write = cnt > free_cnt ? free_cnt : cnt; cnt2 = rb->write_ptr + to_write; if (cnt2 > rb->size) { n1 = rb->size - rb->write_ptr; n2 = cnt2 & rb->size_mask; } else { n1 = to_write; n2 = 0; } memcpy (&(rb->buf[rb->write_ptr]), src, n1); rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; if (n2) { memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; } return to_write; } /* Advance the read pointer `cnt' places. */ LIB_EXPORT void jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt) { size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; rb->read_ptr = tmp; } /* Advance the write pointer `cnt' places. */ LIB_EXPORT void jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt) { size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; rb->write_ptr = tmp; } /* The non-copying data reader. `vec' is an array of two places. Set the values at `vec' to hold the current readable data at `rb'. If the readable data is in one segment the second segment has zero length. */ LIB_EXPORT void jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb, jack_ringbuffer_data_t * vec) { size_t free_cnt; size_t cnt2; size_t w, r; w = rb->write_ptr; r = rb->read_ptr; if (w > r) { free_cnt = w - r; } else { free_cnt = (w - r + rb->size) & rb->size_mask; } cnt2 = r + free_cnt; if (cnt2 > rb->size) { /* Two part vector: the rest of the buffer after the current write ptr, plus some from the start of the buffer. */ vec[0].buf = &(rb->buf[r]); vec[0].len = rb->size - r; vec[1].buf = rb->buf; vec[1].len = cnt2 & rb->size_mask; } else { /* Single part vector: just the rest of the buffer */ vec[0].buf = &(rb->buf[r]); vec[0].len = free_cnt; vec[1].len = 0; } } /* The non-copying data writer. `vec' is an array of two places. Set the values at `vec' to hold the current writeable data at `rb'. If the writeable data is in one segment the second segment has zero length. */ LIB_EXPORT void jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb, jack_ringbuffer_data_t * vec) { size_t free_cnt; size_t cnt2; size_t w, r; w = rb->write_ptr; r = rb->read_ptr; if (w > r) { free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; } else if (w < r) { free_cnt = (r - w) - 1; } else { free_cnt = rb->size - 1; } cnt2 = w + free_cnt; if (cnt2 > rb->size) { /* Two part vector: the rest of the buffer after the current write ptr, plus some from the start of the buffer. */ vec[0].buf = &(rb->buf[w]); vec[0].len = rb->size - w; vec[1].buf = rb->buf; vec[1].len = cnt2 & rb->size_mask; } else { vec[0].buf = &(rb->buf[w]); vec[0].len = free_cnt; vec[1].len = 0; } } 1.9.12~dfsg/common/JackMidiWriteQueue.h0000644000000000000000000000542313214314510016500 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiWriteQueue__ #define __JackMidiWriteQueue__ #include "JackMidiPort.h" namespace Jack { /** * Interface for classes that act as write queues for MIDI messages. Write * queues are used by processors to transfer data to the next processor. */ class SERVER_EXPORT JackMidiWriteQueue { public: enum EnqueueResult { BUFFER_FULL, BUFFER_TOO_SMALL, EVENT_EARLY, EN_ERROR, OK }; virtual ~JackMidiWriteQueue(); /** * Enqueues a data packet in the write queue of `size` bytes contained * in `buffer` that will be sent the absolute time specified by `time`. * This method should not block unless 1.) this write queue represents * the actual outbound MIDI connection, 2.) the MIDI event is being * sent *now*, meaning that `time` is less than or equal to *now*, and * 3.) the method is *not* being called in the process thread. The * method should return `OK` if the event was enqueued, `BUFFER_FULL` * if the write queue isn't able to accept the event right now, * `BUFFER_TOO_SMALL` if this write queue will never be able to accept * the event because the event is too large, `EVENT_EARLY` if this * queue cannot schedule events ahead of time, and `EN_ERROR` if an error * occurs that cannot be specified by another return code. */ virtual EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) = 0; /** * A wrapper method for the `EnqueueEvent` method above. The optional * 'frame_offset' argument is an amount of frames to add to the event's * time. */ inline EnqueueResult EnqueueEvent(jack_midi_event_t *event, jack_nframes_t frame_offset=0) { return EnqueueEvent(event->time + frame_offset, event->size, event->buffer); } }; } #endif 1.9.12~dfsg/common/JackDriver.h0000644000000000000000000002043213214314510015026 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackDriver__ #define __JackDriver__ #include "types.h" #include "JackClientInterface.h" #include "JackConstants.h" #include "JackPlatformPlug.h" #include "JackClientControl.h" #include namespace Jack { class JackLockedEngine; class JackGraphManager; struct JackEngineControl; class JackSlaveDriverInterface; /*! \brief The base interface for drivers. */ class SERVER_EXPORT JackDriverInterface { public: JackDriverInterface() {} virtual ~JackDriverInterface() {} virtual int Open() = 0; virtual int Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) = 0; virtual int Attach() = 0; virtual int Detach() = 0; virtual int Read() = 0; virtual int Write() = 0; virtual int Start() = 0; virtual int Stop() = 0; virtual bool IsFixedBufferSize() = 0; virtual int SetBufferSize(jack_nframes_t buffer_size) = 0; virtual int SetSampleRate(jack_nframes_t sample_rate) = 0; virtual int Process() = 0; virtual void SetMaster(bool onoff) = 0; virtual bool GetMaster() = 0; virtual void AddSlave(JackDriverInterface* slave) = 0; virtual void RemoveSlave(JackDriverInterface* slave) = 0; virtual std::list GetSlaves() = 0; // For "master" driver virtual int ProcessReadSlaves() = 0; virtual int ProcessWriteSlaves() = 0; // For "slave" driver virtual int ProcessRead() = 0; virtual int ProcessWrite() = 0; // For "slave" driver in "synchronous" mode virtual int ProcessReadSync() = 0; virtual int ProcessWriteSync() = 0; // For "slave" driver in "asynchronous" mode virtual int ProcessReadAsync() = 0; virtual int ProcessWriteAsync() = 0; virtual bool IsRealTime() const = 0; virtual bool IsRunning() const = 0; }; /*! \brief The base interface for drivers clients. */ class SERVER_EXPORT JackDriverClientInterface : public JackDriverInterface, public JackClientInterface {}; /*! \brief The base class for drivers. */ #define CaptureDriverFlags static_cast(JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal) #define PlaybackDriverFlags static_cast(JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal) #define MonitorDriverFlags static_cast(JackPortIsOutput) typedef std::list > > driver_connections_list_t; // [type : (src, dst)] class SERVER_EXPORT JackDriver : public JackDriverClientInterface { protected: char fCaptureDriverName[JACK_CLIENT_NAME_SIZE+1]; char fPlaybackDriverName[JACK_CLIENT_NAME_SIZE+1]; char fAliasName[JACK_CLIENT_NAME_SIZE+1]; jack_nframes_t fCaptureLatency; jack_nframes_t fPlaybackLatency; int fCaptureChannels; int fPlaybackChannels; jack_time_t fBeginDateUst; jack_time_t fEndDateUst; float fDelayedUsecs; // Pointers to engine state JackLockedEngine* fEngine; JackGraphManager* fGraphManager; JackSynchro* fSynchroTable; JackEngineControl* fEngineControl; JackClientControl fClientControl; std::list fSlaveList; bool fIsMaster; bool fIsRunning; bool fWithMonitorPorts; // Static tables since the actual number of ports may be changed by the real driver // thus dynamic allocation is more difficult to handle jack_port_id_t fCapturePortList[DRIVER_PORT_NUM]; jack_port_id_t fPlaybackPortList[DRIVER_PORT_NUM]; jack_port_id_t fMonitorPortList[DRIVER_PORT_NUM]; driver_connections_list_t fConnections; // Connections list void CycleIncTime(); void CycleTakeBeginTime(); void CycleTakeEndTime(); void SetupDriverSync(int ref, bool freewheel); void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); // XRun notification sent by the driver void NotifyBufferSize(jack_nframes_t buffer_size); // BufferSize notification sent by the driver void NotifySampleRate(jack_nframes_t sample_rate); // SampleRate notification sent by the driver void NotifyFailure(int code, const char* reason); // Failure notification sent by the driver virtual void SaveConnections(int alias); virtual void LoadConnections(int alias, bool full_name = true); std::string MatchPortName(const char* name, const char** ports, int alias, const std::string& type); virtual int StartSlaves(); virtual int StopSlaves(); virtual int ResumeRefNum(); virtual int SuspendRefNum(); public: JackDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); virtual ~JackDriver(); void SetMaster(bool onoff); bool GetMaster(); void AddSlave(JackDriverInterface* slave); void RemoveSlave(JackDriverInterface* slave); std::list GetSlaves() { return fSlaveList; } virtual int Open(); virtual int Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); virtual int Close(); virtual int Process(); virtual int Attach(); virtual int Detach(); virtual int Read(); virtual int Write(); virtual int Start(); virtual int Stop(); // For "master" driver int ProcessReadSlaves(); int ProcessWriteSlaves(); // For "slave" driver with typically decompose a given cycle in separated Read and Write parts. virtual int ProcessRead(); virtual int ProcessWrite(); // For "slave" driver in "synchronous" mode virtual int ProcessReadSync(); virtual int ProcessWriteSync(); // For "slave" driver in "asynchronous" mode virtual int ProcessReadAsync(); virtual int ProcessWriteAsync(); virtual bool IsFixedBufferSize(); virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetSampleRate(jack_nframes_t sample_rate); virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; virtual bool IsRunning() const { return fIsRunning; } virtual bool Initialize(); // To be called by the wrapping thread Init method when the driver is a "blocking" one }; } // end of namespace #endif 1.9.12~dfsg/common/JackMidiUtil.cpp0000644000000000000000000000577613214314510015664 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackEngineControl.h" #include "JackFrameTimer.h" #include "JackGlobals.h" #include "JackMidiUtil.h" #include "JackTime.h" jack_midi_data_t Jack::ApplyRunningStatus(size_t *size, jack_midi_data_t **buffer, jack_midi_data_t running_status) { // Stolen and modified from alsa/midi_pack.h jack_midi_data_t status = **buffer; if ((status >= 0x80) && (status < 0xf0)) { if (status == running_status) { (*buffer)++; (*size)--; } else { running_status = status; } } else if (status < 0xf8) { running_status = 0; } return running_status; } jack_midi_data_t Jack::ApplyRunningStatus(jack_midi_event_t *event, jack_midi_data_t running_status) { return ApplyRunningStatus(&(event->size), &(event->buffer), running_status); } jack_nframes_t Jack::GetCurrentFrame() { jack_time_t time = GetMicroSeconds(); JackEngineControl *control = GetEngineControl(); JackTimer timer; control->ReadFrameTime(&timer); return timer.Time2Frames(time, control->fBufferSize); } jack_nframes_t Jack::GetFramesFromTime(jack_time_t time) { JackEngineControl* control = GetEngineControl(); JackTimer timer; control->ReadFrameTime(&timer); return timer.Time2Frames(time, control->fBufferSize); } jack_nframes_t Jack::GetLastFrame() { return GetEngineControl()->fFrameTimer.ReadCurrentState()->CurFrame(); } int Jack::GetMessageLength(jack_midi_data_t status_byte) { switch (status_byte & 0xf0) { case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: return 3; case 0xc0: case 0xd0: return 2; case 0xf0: switch (status_byte) { case 0xf0: return 0; case 0xf1: case 0xf3: return 2; case 0xf2: return 3; case 0xf4: case 0xf5: case 0xf7: case 0xfd: break; default: return 1; } } return -1; } jack_time_t Jack::GetTimeFromFrames(jack_nframes_t frames) { JackEngineControl* control = GetEngineControl(); JackTimer timer; control->ReadFrameTime(&timer); return timer.Frames2Time(frames, control->fBufferSize); } 1.9.12~dfsg/common/JackServer.h0000644000000000000000000000701113214314510015037 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackServer__ #define __JackServer__ #include "JackCompilerDeps.h" #include "driver_interface.h" #include "JackDriverLoader.h" #include "JackDriverInfo.h" #include "JackConnectionManager.h" #include "JackGlobals.h" #include "JackPlatformPlug.h" #include "jslist.h" namespace Jack { class JackGraphManager; class JackDriverClientInterface; struct JackEngineControl; class JackLockedEngine; class JackLoadableInternalClient; /*! \brief The Jack server. */ class SERVER_EXPORT JackServer { private: JackDriverInfo* fDriverInfo; JackDriverClientInterface* fAudioDriver; JackDriverClientInterface* fFreewheelDriver; JackDriverClientInterface* fThreadedFreewheelDriver; JackLockedEngine* fEngine; JackEngineControl* fEngineControl; JackGraphManager* fGraphManager; JackServerChannel fRequestChannel; JackConnectionManager fConnectionState; JackSynchro fSynchroTable[CLIENT_NUM]; bool fFreewheel; int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status); public: JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, char self_connect_mode, const char* server_name); ~JackServer(); // Server control int Open(jack_driver_desc_t* driver_desc, JSList* driver_params); int Close(); int Start(); int Stop(); bool IsRunning(); // RT thread void Notify(int refnum, int notify, int value); // From request thread : API int SetBufferSize(jack_nframes_t buffer_size); int SetFreewheel(bool onoff); // Internals clients int InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status); int InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status); // Internal session file int LoadInternalSessionFile(const char* file); // Transport management int ReleaseTimebase(int refnum); int SetTimebaseCallback(int refnum, int conditional); // Backend management JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params); void RemoveSlave(JackDriverInfo* info); int SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params); // Object access JackLockedEngine* GetEngine(); JackEngineControl* GetEngineControl(); JackSynchro* GetSynchroTable(); JackGraphManager* GetGraphManager(); }; } // end of namespace #endif 1.9.12~dfsg/common/JackMidiBufferWriteQueue.h0000644000000000000000000000316313214314510017631 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiBufferWriteQueue__ #define __JackMidiBufferWriteQueue__ #include "JackMidiWriteQueue.h" namespace Jack { /** * Wrapper class to present a JackMidiBuffer in a write queue interface. */ class SERVER_EXPORT JackMidiBufferWriteQueue: public JackMidiWriteQueue { private: JackMidiBuffer *buffer; jack_nframes_t last_frame_time; size_t max_bytes; jack_nframes_t next_frame_time; public: using JackMidiWriteQueue::EnqueueEvent; JackMidiBufferWriteQueue(); EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); /** * This method must be called each period to reset the MIDI buffer for * processing. */ void ResetMidiBuffer(JackMidiBuffer *buffer, jack_nframes_t frames); }; } #endif 1.9.12~dfsg/common/JackFreewheelDriver.h0000644000000000000000000000270213214314510016655 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackFreewheelDriver__ #define __JackFreewheelDriver__ #include "JackDriver.h" namespace Jack { /*! \brief The FreeWheel driver : run Jack engine at full speed. */ class JackFreewheelDriver : public JackDriver { protected: int SuspendRefNum(); public: JackFreewheelDriver(JackLockedEngine* engine, JackSynchro* table): JackDriver("freewheel", "", engine, table) {} virtual ~JackFreewheelDriver() {} bool IsRealTime() const { return false; } int Process(); int ProcessReadSync(); int ProcessWriteSync(); int ProcessReadAsync(); int ProcessWriteAsync(); }; } // end of namespace #endif 1.9.12~dfsg/common/JackRequestDecoder.cpp0000644000000000000000000003245613214314510017055 0ustar rootroot/* Copyright (C) 2012 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackRequestDecoder.h" #include "JackServer.h" #include "JackLockedEngine.h" #include "JackChannel.h" #include #include using namespace std; namespace Jack { #define CheckRead(req, socket) { if (req.Read(socket) < 0) { jack_error("CheckRead error"); return -1; } } #define CheckWriteName(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error name = %s", error, req.fName); } } #define CheckWriteRefNum(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error ref = %d", error, req.fRefNum); } } #define CheckWrite(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error", error); } } JackRequestDecoder::JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler) :fServer(server), fHandler(handler) {} JackRequestDecoder::~JackRequestDecoder() {} int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* socket, int type_aux) { JackRequest::RequestType type = (JackRequest::RequestType)type_aux; // Read data switch (type) { case JackRequest::kClientCheck: { jack_log("JackRequest::ClientCheck"); JackClientCheckRequest req; JackClientCheckResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus); CheckWriteName("JackRequest::ClientCheck", socket); // Atomic ClientCheck followed by ClientOpen on same socket if (req.fOpen) { JackRequest header; header.Read(socket); return HandleRequest(socket, header.fType); } break; } case JackRequest::kClientOpen: { jack_log("JackRequest::ClientOpen"); JackClientOpenRequest req; JackClientOpenResult res; CheckRead(req, socket); fHandler->ClientAdd(socket, &req, &res); CheckWriteName("JackRequest::ClientOpen", socket); break; } case JackRequest::kClientClose: { jack_log("JackRequest::ClientClose"); JackClientCloseRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum); CheckWriteRefNum("JackRequest::ClientClose", socket); fHandler->ClientRemove(socket, req.fRefNum); // Will cause the wrapping thread to stop return -1; } case JackRequest::kActivateClient: { JackActivateRequest req; JackResult res; jack_log("JackRequest::ActivateClient"); CheckRead(req, socket); res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); CheckWriteRefNum("JackRequest::ActivateClient", socket); break; } case JackRequest::kDeactivateClient: { jack_log("JackRequest::DeactivateClient"); JackDeactivateRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum); CheckWriteRefNum("JackRequest::DeactivateClient", socket); break; } case JackRequest::kRegisterPort: { jack_log("JackRequest::RegisterPort"); JackPortRegisterRequest req; JackPortRegisterResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex); CheckWriteRefNum("JackRequest::RegisterPort", socket); break; } case JackRequest::kUnRegisterPort: { jack_log("JackRequest::UnRegisterPort"); JackPortUnRegisterRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex); CheckWriteRefNum("JackRequest::UnRegisterPort", socket); break; } case JackRequest::kConnectNamePorts: { jack_log("JackRequest::ConnectNamePorts"); JackPortConnectNameRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst); CheckWriteRefNum("JackRequest::ConnectNamePorts", socket); break; } case JackRequest::kDisconnectNamePorts: { jack_log("JackRequest::DisconnectNamePorts"); JackPortDisconnectNameRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst); CheckWriteRefNum("JackRequest::DisconnectNamePorts", socket); break; } case JackRequest::kConnectPorts: { jack_log("JackRequest::ConnectPorts"); JackPortConnectRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst); CheckWriteRefNum("JackRequest::ConnectPorts", socket); break; } case JackRequest::kDisconnectPorts: { jack_log("JackRequest::DisconnectPorts"); JackPortDisconnectRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst); CheckWriteRefNum("JackRequest::DisconnectPorts", socket); break; } case JackRequest::kPortRename: { jack_log("JackRequest::PortRename"); JackPortRenameRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName); CheckWriteRefNum("JackRequest::PortRename", socket); break; } case JackRequest::kSetBufferSize: { jack_log("JackRequest::SetBufferSize"); JackSetBufferSizeRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->SetBufferSize(req.fBufferSize); CheckWrite("JackRequest::SetBufferSize", socket); break; } case JackRequest::kSetFreeWheel: { jack_log("JackRequest::SetFreeWheel"); JackSetFreeWheelRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->SetFreewheel(req.fOnOff); CheckWrite("JackRequest::SetFreeWheel", socket); break; } case JackRequest::kComputeTotalLatencies: { jack_log("JackRequest::ComputeTotalLatencies"); JackComputeTotalLatenciesRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->ComputeTotalLatencies(); CheckWrite("JackRequest::ComputeTotalLatencies", socket); break; } case JackRequest::kReleaseTimebase: { jack_log("JackRequest::ReleaseTimebase"); JackReleaseTimebaseRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->ReleaseTimebase(req.fRefNum); CheckWriteRefNum("JackRequest::ReleaseTimebase", socket); break; } case JackRequest::kSetTimebaseCallback: { jack_log("JackRequest::SetTimebaseCallback"); JackSetTimebaseCallbackRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal); CheckWriteRefNum("JackRequest::SetTimebaseCallback", socket); break; } case JackRequest::kGetInternalClientName: { jack_log("JackRequest::GetInternalClientName"); JackGetInternalClientNameRequest req; JackGetInternalClientNameResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName); CheckWriteRefNum("JackRequest::GetInternalClientName", socket); break; } case JackRequest::kInternalClientHandle: { jack_log("JackRequest::InternalClientHandle"); JackInternalClientHandleRequest req; JackInternalClientHandleResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum); CheckWriteRefNum("JackRequest::InternalClientHandle", socket); break; } case JackRequest::kInternalClientLoad: { jack_log("JackRequest::InternalClientLoad"); JackInternalClientLoadRequest req; JackInternalClientLoadResult res; CheckRead(req, socket); res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); CheckWriteName("JackRequest::InternalClientLoad", socket); break; } case JackRequest::kInternalClientUnload: { jack_log("JackRequest::InternalClientUnload"); JackInternalClientUnloadRequest req; JackInternalClientUnloadResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus); CheckWriteRefNum("JackRequest::InternalClientUnload", socket); break; } case JackRequest::kNotification: { jack_log("JackRequest::Notification"); JackClientNotificationRequest req; CheckRead(req, socket); if (req.fNotify == kQUIT) { jack_log("JackRequest::Notification kQUIT"); throw JackQuitException(); } else { fServer->Notify(req.fRefNum, req.fNotify, req.fValue); } break; } case JackRequest::kSessionNotify: { jack_log("JackRequest::SessionNotify"); JackSessionNotifyRequest req; CheckRead(req, socket); fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket, NULL); break; } case JackRequest::kSessionReply: { jack_log("JackRequest::SessionReply"); JackSessionReplyRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->SessionReply(req.fRefNum); CheckWrite("JackRequest::SessionReply", socket); break; } case JackRequest::kGetClientByUUID: { jack_log("JackRequest::GetClientByUUID"); JackGetClientNameRequest req; JackClientNameResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName); CheckWrite("JackRequest::GetClientByUUID", socket); break; } case JackRequest::kGetUUIDByClient: { jack_log("JackRequest::GetUUIDByClient"); JackGetUUIDRequest req; JackUUIDResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID); CheckWrite("JackRequest::GetUUIDByClient", socket); break; } case JackRequest::kReserveClientName: { jack_log("JackRequest::ReserveClientName"); JackReserveNameRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID); CheckWrite("JackRequest::ReserveClientName", socket); break; } case JackRequest::kClientHasSessionCallback: { jack_log("JackRequest::ClientHasSessionCallback"); JackClientHasSessionCallbackRequest req; JackResult res; CheckRead(req, socket); res.fResult = fServer->GetEngine()->ClientHasSessionCallback(req.fName); CheckWrite("JackRequest::ClientHasSessionCallback", socket); break; } default: jack_error("Unknown request %ld", type); return -1; } return 0; } } // end of namespace 1.9.12~dfsg/common/JackMidiAsyncQueue.h0000644000000000000000000000576213214314510016471 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiAsyncQueue__ #define __JackMidiAsyncQueue__ #include "JackMidiPort.h" #include "JackMidiReadQueue.h" #include "JackMidiWriteQueue.h" #include "ringbuffer.h" namespace Jack { /** * This is a MIDI message queue designed to allow one thread to pass MIDI * messages to another thread (though it can also be used to buffer events * internally). This is especially useful if the MIDI API you're * attempting to interface with doesn't provide the ability to schedule * MIDI events ahead of time and/or has blocking send/receive calls, as it * allows a separate thread to handle input/output while the JACK process * thread copies events from a MIDI buffer to this queue, or vice versa. */ class SERVER_EXPORT JackMidiAsyncQueue: public JackMidiReadQueue, public JackMidiWriteQueue { private: static const size_t INFO_SIZE = sizeof(jack_nframes_t) + sizeof(size_t); jack_ringbuffer_t *byte_ring; jack_midi_data_t *data_buffer; jack_midi_event_t dequeue_event; jack_ringbuffer_t *info_ring; size_t max_bytes; public: using JackMidiWriteQueue::EnqueueEvent; /** * Creates a new asynchronous MIDI message queue. The queue can store * up to `max_messages` MIDI messages and up to `max_bytes` of MIDI * data before it starts rejecting messages. */ JackMidiAsyncQueue(size_t max_bytes=4096, size_t max_messages=1024); virtual ~JackMidiAsyncQueue(); /** * Dequeues and returns a MIDI event. Returns '0' if there are no MIDI * events available. This method may be overridden. */ virtual jack_midi_event_t * DequeueEvent(); /** * Enqueues the MIDI event specified by the arguments. The return * value indiciates whether or not the event was successfully enqueued. * This method may be overridden. */ virtual EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); /** * Returns the maximum size event that can be enqueued right *now*. */ size_t GetAvailableSpace(); }; } #endif 1.9.12~dfsg/common/netjack_packet.h0000644000000000000000000001304313214314510015750 0ustar rootroot /* * NetJack - Packet Handling functions * * used by the driver and the jacknet_client * * Copyright (C) 2006 Torben Hohn * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $ * */ #ifndef __JACK_NET_PACKET_H__ #define __JACK_NET_PACKET_H__ #ifdef __cplusplus extern "C" { #endif #include #include #include #include // The Packet Header. #define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression #define OPUS_MODE 999 // Magic bitdepth value that indicates OPUS compression #define MASTER_FREEWHEELS 0x80000000 typedef struct _jacknet_packet_header jacknet_packet_header; struct _jacknet_packet_header { // General AutoConf Data jack_nframes_t capture_channels_audio; jack_nframes_t playback_channels_audio; jack_nframes_t capture_channels_midi; jack_nframes_t playback_channels_midi; jack_nframes_t period_size; jack_nframes_t sample_rate; // Transport Sync jack_nframes_t sync_state; jack_nframes_t transport_frame; jack_nframes_t transport_state; // Packet loss Detection, and latency reduction jack_nframes_t framecnt; jack_nframes_t latency; jack_nframes_t reply_port; jack_nframes_t mtu; jack_nframes_t fragment_nr; }; typedef union _int_float int_float_t; union _int_float { uint32_t i; float f; }; // fragment reorder cache. typedef struct _cache_packet cache_packet; struct _cache_packet { int valid; int num_fragments; int packet_size; int mtu; jack_time_t recv_timestamp; jack_nframes_t framecnt; char * fragment_array; char * packet_buf; }; typedef struct _packet_cache packet_cache; struct _packet_cache { int size; cache_packet *packets; int mtu; struct sockaddr_in master_address; int master_address_valid; jack_nframes_t last_framecnt_retreived; int last_framecnt_retreived_valid; }; // fragment cache function prototypes // XXX: Some of these are private. packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu); void packet_cache_free(packet_cache *pkt_cache); cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt); cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache); cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache); void cache_packet_reset(cache_packet *pack); void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt); void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len); int cache_packet_is_complete(cache_packet *pack); void packet_cache_drain_socket( packet_cache *pcache, int sockfd ); void packet_cache_reset_master_address( packet_cache *pcache ); float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ); int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ); int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ); int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt ); int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); // Function Prototypes int netjack_poll_deadline (int sockfd, jack_time_t deadline); void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu); int get_sample_size(int bitdepth); void packet_header_hton(jacknet_packet_header *pkthdr); void packet_header_ntoh(jacknet_packet_header *pkthdr); void render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats ); void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); // XXX: This is sort of deprecated: // This one waits forever. an is not using ppoll int netjack_poll(int sockfd, int timeout); void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/common/JackRestartThreadedDriver.cpp0000644000000000000000000000300513214314510020364 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackRestartThreadedDriver.h" #include "JackException.h" namespace Jack { bool JackRestartThreadedDriver::Execute() { try { // Keep running even in case of error while (fThread.GetStatus() == JackThread::kRunning) { Process(); } return false; } catch (JackNetException& e) { e.PrintMessage(); jack_info("Driver is restarted"); fThread.DropSelfRealTime(); // Thread in kIniting status again... fThread.SetStatus(JackThread::kIniting); if (Init()) { // Thread in kRunning status again... fThread.SetStatus(JackThread::kRunning); return true; } else { return false; } } } } // end of namespace 1.9.12~dfsg/common/JackFrameTimer.cpp0000644000000000000000000002103113214314510016155 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackFrameTimer.h" #include "JackError.h" #include #include namespace Jack { #if defined(WIN32) && !defined(__MINGW32__) /* missing on Windows : see http://bugs.mysql.com/bug.php?id=15936 */ inline double rint(double nr) { double f = floor(nr); double c = ceil(nr); return (((c -nr) >= (nr - f)) ? f : c); } #endif JackTimer::JackTimer() { fInitialized = false; fFrames = 0; fCurrentWakeup = 0; fCurrentCallback = 0; fNextWakeUp = 0; fPeriodUsecs = 0.0f; fFilterOmega = 0.0f; /* Initialised later */ } jack_nframes_t JackTimer::Time2Frames(jack_time_t usecs, jack_nframes_t buffer_size) { if (fInitialized) { /* Make sure we have signed differences. It would make a lot of sense to use the standard signed intNN_t types everywhere instead of e.g. jack_nframes_t and jack_time_t. This would at least ensure that the types used below are the correct ones. There is no way to get a type that would be 'a signed version of jack_time_t' for example - the types below are inherently fragile and there is no automatic way to check they are the correct ones. The only way is to check manually against jack/types.h. FA - 16/02/2012 */ int64_t du = usecs - fCurrentWakeup; int64_t dp = fNextWakeUp - fCurrentWakeup; return fFrames + (int32_t)rint((double)du / (double)dp * buffer_size); } else { return 0; } } jack_time_t JackTimer::Frames2Time(jack_nframes_t frames, jack_nframes_t buffer_size) { if (fInitialized) { /* Make sure we have signed differences. It would make a lot of sense to use the standard signed intNN_t types everywhere instead of e.g. jack_nframes_t and jack_time_t. This would at least ensure that the types used below are the correct ones. There is no way to get a type that would be 'a signed version of jack_time_t' for example - the types below are inherently fragile and there is no automatic way to check they are the correct ones. The only way is to check manually against jack/types.h. FA - 16/02/2012 */ int32_t df = frames - fFrames; int64_t dp = fNextWakeUp - fCurrentWakeup; return fCurrentWakeup + (int64_t)rint((double) df * (double) dp / buffer_size); } else { return 0; } } int JackTimer::GetCycleTimes(jack_nframes_t* current_frames, jack_time_t* current_usecs, jack_time_t* next_usecs, float* period_usecs) { if (fInitialized) { *current_frames = fFrames; *current_usecs = fCurrentWakeup; *next_usecs = fNextWakeUp; *period_usecs = fPeriodUsecs; return 0; } else { return -1; } } jack_nframes_t JackTimer::FramesSinceCycleStart(jack_time_t cur_time, jack_nframes_t frames_rate) { return (jack_nframes_t) floor((((float)frames_rate) / 1000000.0f) * (cur_time - fCurrentCallback)); } void JackFrameTimer::InitFrameTime() { fFirstWakeUp = true; } void JackFrameTimer::IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs) { if (fFirstWakeUp) { InitFrameTimeAux(callback_usecs, period_usecs); fFirstWakeUp = false; } IncFrameTimeAux(buffer_size, callback_usecs, period_usecs); } void JackFrameTimer::ResetFrameTime(jack_time_t callback_usecs) { if (!fFirstWakeUp) { // ResetFrameTime may be called by a xrun/delayed wakeup on the first cycle JackTimer* timer = WriteNextStateStart(); timer->fCurrentWakeup = callback_usecs; timer->fCurrentCallback = callback_usecs; WriteNextStateStop(); TrySwitchState(); // always succeed since there is only one writer } } /* Use the state returned by ReadCurrentState and check that the state was not changed during the read operation. The operation is lock-free since there is no intermediate state in the write operation that could cause the read to loop forever. */ void JackFrameTimer::ReadFrameTime(JackTimer* timer) { UInt16 next_index = GetCurrentIndex(); UInt16 cur_index; do { cur_index = next_index; memcpy(timer, ReadCurrentState(), sizeof(JackTimer)); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read } // Internal void JackFrameTimer::InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t period_usecs) { /* the first wakeup or post-freewheeling or post-xrun */ /* There seems to be no significant difference between the two conditions OR-ed above. Incrementing the frame_time after an xrun shouldn't harm, as there will be a discontinuity anyway. So the two are combined in this version. FA 16/03/2012 */ /* Since the DLL *will* be run, next_wakeup should be the current wakeup time *without* adding the period time, as if it were computed in the previous period. FA 16/03/2012 */ /* Added initialisation of timer->period_usecs, required due to the modified implementation of the DLL itself. OTOH, this should maybe not be repeated after e.g. freewheeling or an xrun, as the current value would be more accurate than the nominal one. But it doesn't really harm either. Implementing this would require a new flag in the engine structure, to be used after freewheeling or an xrun instead of first_wakeup. I don't know if this can be done without breaking compatibility, so I did not add this FA 13/02/2012 */ /* Added initialisation of timer->filter_omega. This makes the DLL bandwidth independent of the actual period time. The bandwidth is now 1/8 Hz in all cases. The value of timer->filter_omega is 2 * pi * BW * Tperiod. FA 13/02/2012 */ JackTimer* timer = WriteNextStateStart(); timer->fPeriodUsecs = (float)period_usecs; timer->fCurrentCallback = callback_usecs; timer->fNextWakeUp = callback_usecs; timer->fFilterOmega = period_usecs * 7.854e-7f; WriteNextStateStop(); TrySwitchState(); // always succeed since there is only one writer } void JackFrameTimer::IncFrameTimeAux(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs) { JackTimer* timer = WriteNextStateStart(); /* Modified implementation (the actual result is the same). 'fSecondOrderIntegrator' is renamed to 'fPeriodUsecs' and now represents the DLL's best estimate of the period time in microseconds (before it was a scaled version of the difference w.r.t. the nominal value). This allows this value to be made available to clients that are interested in it (see jack_get_cycle_times). This change also means that 'fPeriodUsecs' must be initialised to the nominal period time instead of zero. This is done in the first cycle in jack_run_cycle(). 'fFilterCoefficient' is renamed to 'fFilterOmega'. It is now equal to the 'omega' value as defined in the 'Using a DLL to filter time' paper (before it was a scaled version of this value). It is computed once in jack_run_cycle() rather than set to a fixed value. This makes the DLL bandwidth independent of the period time. FA 13/02/2012 */ float delta = (float)((int64_t)callback_usecs - (int64_t)timer->fNextWakeUp); delta *= timer->fFilterOmega; timer->fCurrentWakeup = timer->fNextWakeUp; timer->fCurrentCallback = callback_usecs; timer->fFrames += buffer_size; timer->fPeriodUsecs += timer->fFilterOmega * delta; timer->fNextWakeUp += (int64_t)floorf(timer->fPeriodUsecs + 1.41f * delta + 0.5f); timer->fInitialized = true; WriteNextStateStop(); TrySwitchState(); // always succeed since there is only one writer } } // end of namespace 1.9.12~dfsg/common/JackMidiSendQueue.cpp0000644000000000000000000000172613214314510016634 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMidiSendQueue.h" #include "JackMidiUtil.h" using Jack::JackMidiSendQueue; JackMidiSendQueue::~JackMidiSendQueue() { // Empty } jack_nframes_t JackMidiSendQueue::GetNextScheduleFrame() { return GetCurrentFrame(); } 1.9.12~dfsg/common/JackGenericClientChannel.h0000644000000000000000000001016713214314510017603 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackGenericClientChannel__ #define __JackGenericClientChannel__ #include "JackChannel.h" namespace Jack { struct JackRequest; struct JackResult; /*! \brief Generic JackClientChannel class. */ class JackGenericClientChannel : public detail::JackClientChannelInterface { protected: detail::JackClientRequestInterface* fRequest; void ServerSyncCall(JackRequest* req, JackResult* res, int* result); void ServerAsyncCall(JackRequest* req, JackResult* res, int* result); public: JackGenericClientChannel(); virtual ~JackGenericClientChannel(); virtual int Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) { return -1; } virtual void Close() {} virtual int Start() { return -1; } virtual void Stop() {} int ServerCheck(const char* server_name); void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open); void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); void ClientClose(int refnum, int* result); void ClientActivate(int refnum, int is_real_time, int* result); void ClientDeactivate(int refnum, int* result); void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); void PortUnRegister(int refnum, jack_port_id_t port_index, int* result); void PortConnect(int refnum, const char* src, const char* dst, int* result); void PortDisconnect(int refnum, const char* src, const char* dst, int* result); void PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); void PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); void PortRename(int refnum, jack_port_id_t port, const char* name, int* result); void SetBufferSize(jack_nframes_t buffer_size, int* result); void SetFreewheel(int onoff, int* result); void ComputeTotalLatencies(int* result); void ReleaseTimebase(int refnum, int* result); void SetTimebaseCallback(int refnum, int conditional, int* result); void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result); void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result); void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result); void InternalClientUnload(int refnum, int int_ref, int* status, int* result); // Session API void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); void SessionReply(int refnum, int* result); void GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result); void GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result); void ReserveClientName(int refnum, const char* client_name, const char *uuid, int* result); void ClientHasSessionCallback(const char* client_name, int* result); }; } // end of namespace #endif 1.9.12~dfsg/common/netjack_packet.c0000644000000000000000000013557013214314510015755 0ustar rootroot /* * NetJack - Packet Handling functions * * used by the driver and the jacknet_client * * Copyright (C) 2008 Marc-Olivier Barre * Copyright (C) 2008 Pieter Palmers * Copyright (C) 2006 Torben Hohn * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $ * */ #if defined(HAVE_CONFIG_H) #include "config.h" #endif #ifdef __APPLE__ #define _DARWIN_C_SOURCE #endif #if HAVE_PPOLL #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #ifdef WIN32 #include #define socklen_t int #include #define socklen_t int #else #include #include #include #endif #include #include #if HAVE_SAMPLERATE #include #endif #if HAVE_CELT #include #endif #if HAVE_OPUS #include #include #endif #include "netjack_packet.h" #include "JackError.h" #ifdef NO_JACK_ERROR #define jack_error printf #endif int fraggo = 0; void packet_header_hton (jacknet_packet_header *pkthdr) { pkthdr->capture_channels_audio = htonl(pkthdr->capture_channels_audio); pkthdr->playback_channels_audio = htonl(pkthdr->playback_channels_audio); pkthdr->capture_channels_midi = htonl(pkthdr->capture_channels_midi); pkthdr->playback_channels_midi = htonl(pkthdr->playback_channels_midi); pkthdr->period_size = htonl(pkthdr->period_size); pkthdr->sample_rate = htonl(pkthdr->sample_rate); pkthdr->sync_state = htonl(pkthdr->sync_state); pkthdr->transport_frame = htonl(pkthdr->transport_frame); pkthdr->transport_state = htonl(pkthdr->transport_state); pkthdr->framecnt = htonl(pkthdr->framecnt); pkthdr->latency = htonl(pkthdr->latency); pkthdr->reply_port = htonl(pkthdr->reply_port); pkthdr->mtu = htonl(pkthdr->mtu); pkthdr->fragment_nr = htonl(pkthdr->fragment_nr); } void packet_header_ntoh (jacknet_packet_header *pkthdr) { pkthdr->capture_channels_audio = ntohl(pkthdr->capture_channels_audio); pkthdr->playback_channels_audio = ntohl(pkthdr->playback_channels_audio); pkthdr->capture_channels_midi = ntohl(pkthdr->capture_channels_midi); pkthdr->playback_channels_midi = ntohl(pkthdr->playback_channels_midi); pkthdr->period_size = ntohl(pkthdr->period_size); pkthdr->sample_rate = ntohl(pkthdr->sample_rate); pkthdr->sync_state = ntohl(pkthdr->sync_state); pkthdr->transport_frame = ntohl(pkthdr->transport_frame); pkthdr->transport_state = ntohl(pkthdr->transport_state); pkthdr->framecnt = ntohl(pkthdr->framecnt); pkthdr->latency = ntohl(pkthdr->latency); pkthdr->reply_port = ntohl(pkthdr->reply_port); pkthdr->mtu = ntohl(pkthdr->mtu); pkthdr->fragment_nr = ntohl(pkthdr->fragment_nr); } int get_sample_size (int bitdepth) { if (bitdepth == 8) return sizeof (int8_t); if (bitdepth == 16) return sizeof (int16_t); //JN: why? is this for buffer sizes before or after encoding? //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? if( bitdepth == CELT_MODE ) return sizeof( unsigned char ); if( bitdepth == OPUS_MODE ) return sizeof( unsigned char ); return sizeof (int32_t); } int jack_port_is_audio(const char *porttype) { return (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0); } int jack_port_is_midi(const char *porttype) { return (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0); } // fragment management functions. packet_cache *packet_cache_new (int num_packets, int pkt_size, int mtu) { int fragment_payload_size = mtu - sizeof (jacknet_packet_header); int i, fragment_number; if( pkt_size == sizeof(jacknet_packet_header) ) fragment_number = 1; else fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1; packet_cache *pcache = malloc (sizeof (packet_cache)); if (pcache == NULL) { jack_error ("could not allocate packet cache (1)"); return NULL; } pcache->size = num_packets; pcache->packets = malloc (sizeof (cache_packet) * num_packets); pcache->master_address_valid = 0; pcache->last_framecnt_retreived = 0; pcache->last_framecnt_retreived_valid = 0; if (pcache->packets == NULL) { jack_error ("could not allocate packet cache (2)"); return NULL; } for (i = 0; i < num_packets; i++) { pcache->packets[i].valid = 0; pcache->packets[i].num_fragments = fragment_number; pcache->packets[i].packet_size = pkt_size; pcache->packets[i].mtu = mtu; pcache->packets[i].framecnt = 0; pcache->packets[i].fragment_array = malloc (sizeof (char) * fragment_number); pcache->packets[i].packet_buf = malloc (pkt_size); if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL)) { jack_error ("could not allocate packet cache (3)"); return NULL; } } pcache->mtu = mtu; return pcache; } void packet_cache_free (packet_cache *pcache) { int i; if( pcache == NULL ) return; for (i = 0; i < pcache->size; i++) { free (pcache->packets[i].fragment_array); free (pcache->packets[i].packet_buf); } free (pcache->packets); free (pcache); } cache_packet *packet_cache_get_packet (packet_cache *pcache, jack_nframes_t framecnt) { int i; cache_packet *retval; for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) return &(pcache->packets[i]); } // The Packet is not in the packet cache. // find a free packet. retval = packet_cache_get_free_packet (pcache); if (retval != NULL) { cache_packet_set_framecnt (retval, framecnt); return retval; } // No Free Packet available // Get The Oldest packet and reset it. retval = packet_cache_get_oldest_packet (pcache); //printf( "Dropping %d from Cache :S\n", retval->framecnt ); cache_packet_reset (retval); cache_packet_set_framecnt (retval, framecnt); return retval; } // TODO: fix wrapping case... need to pass // current expected frame here. // // or just save framecount into packet_cache. cache_packet *packet_cache_get_oldest_packet (packet_cache *pcache) { jack_nframes_t minimal_frame = JACK_MAX_FRAMES; cache_packet *retval = &(pcache->packets[0]); int i; for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame)) { minimal_frame = pcache->packets[i].framecnt; retval = &(pcache->packets[i]); } } return retval; } cache_packet *packet_cache_get_free_packet (packet_cache *pcache) { int i; for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid == 0) return &(pcache->packets[i]); } return NULL; } void cache_packet_reset (cache_packet *pack) { int i; pack->valid = 0; // XXX: i dont think this is necessary here... // fragement array is cleared in _set_framecnt() for (i = 0; i < pack->num_fragments; i++) pack->fragment_array[i] = 0; } void cache_packet_set_framecnt (cache_packet *pack, jack_nframes_t framecnt) { int i; pack->framecnt = framecnt; for (i = 0; i < pack->num_fragments; i++) pack->fragment_array[i] = 0; pack->valid = 1; } void cache_packet_add_fragment (cache_packet *pack, char *packet_buf, int rcv_len) { jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf; int fragment_payload_size = pack->mtu - sizeof (jacknet_packet_header); char *packet_bufX = pack->packet_buf + sizeof (jacknet_packet_header); char *dataX = packet_buf + sizeof (jacknet_packet_header); jack_nframes_t fragment_nr = ntohl (pkthdr->fragment_nr); jack_nframes_t framecnt = ntohl (pkthdr->framecnt); if (framecnt != pack->framecnt) { jack_error ("errror. framecnts dont match"); return; } if (fragment_nr == 0) { memcpy (pack->packet_buf, packet_buf, rcv_len); pack->fragment_array[0] = 1; return; } if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0)) { if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header))) { memcpy (packet_bufX + fragment_nr * fragment_payload_size, dataX, rcv_len - sizeof (jacknet_packet_header)); pack->fragment_array[fragment_nr] = 1; } else jack_error ("too long packet received..."); } } int cache_packet_is_complete (cache_packet *pack) { int i; for (i = 0; i < pack->num_fragments; i++) if (pack->fragment_array[i] == 0) return 0; return 1; } #ifndef WIN32 // new poll using nanoseconds resolution and // not waiting forever. int netjack_poll_deadline (int sockfd, jack_time_t deadline) { struct pollfd fds; int poll_err = 0; #if HAVE_PPOLL struct timespec timeout_spec = { 0, 0 }; #else int timeout; #endif jack_time_t now = jack_get_time(); if( now >= deadline ) return 0; if( (deadline - now) >= 1000000 ) { jack_error( "deadline more than 1 second in the future, trimming it." ); deadline = now + 500000; } #if HAVE_PPOLL timeout_spec.tv_nsec = (deadline - now) * 1000; #else timeout = lrintf( (float)(deadline - now) / 1000.0 ); #endif fds.fd = sockfd; fds.events = POLLIN; #if HAVE_PPOLL poll_err = ppoll (&fds, 1, &timeout_spec, NULL); #else poll_err = poll (&fds, 1, timeout); #endif if (poll_err == -1) { switch (errno) { case EBADF: jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); break; case EFAULT: jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); break; case EINTR: jack_error ("Error %d: A signal occurred before any requested event", errno); break; case EINVAL: jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); break; case ENOMEM: jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); break; } } return poll_err; } int netjack_poll (int sockfd, int timeout) { struct pollfd fds; int i, poll_err = 0; sigset_t sigmask, rsigmask; struct sigaction action; sigemptyset(&sigmask); sigaddset(&sigmask, SIGHUP); sigaddset(&sigmask, SIGINT); sigaddset(&sigmask, SIGQUIT); sigaddset(&sigmask, SIGPIPE); sigaddset(&sigmask, SIGTERM); sigaddset(&sigmask, SIGUSR1); sigaddset(&sigmask, SIGUSR2); action.sa_handler = SIG_DFL; action.sa_mask = sigmask; action.sa_flags = SA_RESTART; for (i = 1; i < NSIG; i++) if (sigismember (&sigmask, i)) sigaction (i, &action, 0); fds.fd = sockfd; fds.events = POLLIN; sigprocmask(SIG_UNBLOCK, &sigmask, &rsigmask); while (poll_err == 0) { poll_err = poll (&fds, 1, timeout); } sigprocmask(SIG_SETMASK, &rsigmask, NULL); if (poll_err == -1) { switch (errno) { case EBADF: jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); break; case EFAULT: jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); break; case EINTR: jack_error ("Error %d: A signal occurred before any requested event", errno); break; case EINVAL: jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); break; case ENOMEM: jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); break; } return 0; } return 1; } #else int netjack_poll (int sockfd, int timeout) { jack_error( "netjack_poll not implemented" ); return 0; } int netjack_poll_deadline (int sockfd, jack_time_t deadline) { fd_set fds; FD_ZERO( &fds ); FD_SET( sockfd, &fds ); struct timeval timeout; while( 1 ) { jack_time_t now = jack_get_time(); if( now >= deadline ) return 0; int timeout_usecs = (deadline - now); //jack_error( "timeout = %d", timeout_usecs ); timeout.tv_sec = 0; timeout.tv_usec = (timeout_usecs < 500) ? 500 : timeout_usecs; timeout.tv_usec = (timeout_usecs > 1000000) ? 500000 : timeout_usecs; int poll_err = select (0, &fds, NULL, NULL, &timeout); if( poll_err != 0 ) return poll_err; } return 0; } #endif // This now reads all a socket has into the cache. // replacing netjack_recv functions. void packet_cache_drain_socket( packet_cache *pcache, int sockfd ) { char *rx_packet = alloca (pcache->mtu); jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; int rcv_len; jack_nframes_t framecnt; cache_packet *cpack; struct sockaddr_in sender_address; #ifdef WIN32 int senderlen = sizeof( struct sockaddr_in ); u_long parm = 1; ioctlsocket( sockfd, FIONBIO, &parm ); #else unsigned int senderlen = sizeof( struct sockaddr_in ); #endif while (1) { #ifdef WIN32 rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0, (struct sockaddr*) &sender_address, &senderlen); #else rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, MSG_DONTWAIT, (struct sockaddr*) &sender_address, &senderlen); #endif if (rcv_len < 0) return; if (pcache->master_address_valid) { // Verify its from our master. if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0) continue; } else { // Setup this one as master //printf( "setup master...\n" ); memcpy ( &(pcache->master_address), &sender_address, senderlen ); pcache->master_address_valid = 1; } framecnt = ntohl (pkthdr->framecnt); if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived )) continue; cpack = packet_cache_get_packet (pcache, framecnt); cache_packet_add_fragment (cpack, rx_packet, rcv_len); cpack->recv_timestamp = jack_get_time(); } } void packet_cache_reset_master_address( packet_cache *pcache ) { pcache->master_address_valid = 0; pcache->last_framecnt_retreived = 0; pcache->last_framecnt_retreived_valid = 0; } void packet_cache_clear_old_packets (packet_cache *pcache, jack_nframes_t framecnt ) { int i; for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt)) { cache_packet_reset (&(pcache->packets[i])); } } } int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ) { int i; cache_packet *cpack = NULL; for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) { cpack = &(pcache->packets[i]); break; } } if( cpack == NULL ) { //printf( "retreive packet: %d....not found\n", framecnt ); return -1; } if( !cache_packet_is_complete( cpack ) ) { return -1; } // ok. cpack is the one we want and its complete. *packet_buf = cpack->packet_buf; if( timestamp ) *timestamp = cpack->recv_timestamp; pcache->last_framecnt_retreived_valid = 1; pcache->last_framecnt_retreived = framecnt; return pkt_size; } int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ) { int i; cache_packet *cpack = NULL; for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) { cpack = &(pcache->packets[i]); break; } } if( cpack == NULL ) { //printf( "retreive packet: %d....not found\n", framecnt ); return -1; } if( !cache_packet_is_complete( cpack ) ) { return -1; } cache_packet_reset (cpack); packet_cache_clear_old_packets( pcache, framecnt ); return 0; } float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ) { int num_packets_before_us = 0; int i; for (i = 0; i < pcache->size; i++) { cache_packet *cpack = &(pcache->packets[i]); if (cpack->valid && cache_packet_is_complete( cpack )) if( cpack->framecnt >= expected_framecnt ) num_packets_before_us += 1; } return 100.0 * (float)num_packets_before_us / (float)( pcache->size ); } // Returns 0 when no valid packet is inside the cache. int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ) { int i; jack_nframes_t best_offset = JACK_MAX_FRAMES / 2 - 1; int retval = 0; for (i = 0; i < pcache->size; i++) { cache_packet *cpack = &(pcache->packets[i]); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); if (!cpack->valid || !cache_packet_is_complete( cpack )) { //printf( "invalid\n" ); continue; } if( cpack->framecnt < expected_framecnt ) continue; if( (cpack->framecnt - expected_framecnt) > best_offset ) { continue; } best_offset = cpack->framecnt - expected_framecnt; retval = 1; if (best_offset == 0) break; } if (retval && framecnt) *framecnt = expected_framecnt + best_offset; return retval; } int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt ) { int i; jack_nframes_t best_value = 0; int retval = 0; for (i = 0; i < pcache->size; i++) { cache_packet *cpack = &(pcache->packets[i]); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); if (!cpack->valid || !cache_packet_is_complete( cpack )) { //printf( "invalid\n" ); continue; } if (cpack->framecnt < best_value) { continue; } best_value = cpack->framecnt; retval = 1; } if (retval && framecnt) *framecnt = best_value; return retval; } // Returns 0 when no valid packet is inside the cache. int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ) { int i; jack_nframes_t best_offset = 0; int retval = 0; for (i = 0; i < pcache->size; i++) { cache_packet *cpack = &(pcache->packets[i]); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); if (!cpack->valid || !cache_packet_is_complete( cpack )) { //printf( "invalid\n" ); continue; } if ((cpack->framecnt - expected_framecnt) < best_offset) { continue; } best_offset = cpack->framecnt - expected_framecnt; retval = 1; if( best_offset == 0 ) break; } if (retval && framecnt) *framecnt = JACK_MAX_FRAMES - best_offset; return retval; } // fragmented packet IO void netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu) { int frag_cnt = 0; char *tx_packet, *dataX; jacknet_packet_header *pkthdr; tx_packet = alloca (mtu + 10); dataX = tx_packet + sizeof (jacknet_packet_header); pkthdr = (jacknet_packet_header *) tx_packet; int fragment_payload_size = mtu - sizeof (jacknet_packet_header); if (pkt_size <= mtu) { int err; pkthdr = (jacknet_packet_header *) packet_buf; pkthdr->fragment_nr = htonl (0); err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size); if( err < 0 ) { //printf( "error in send\n" ); perror( "send" ); } } else { int err; // Copy the packet header to the tx pack first. memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header)); // Now loop and send all char *packet_bufX = packet_buf + sizeof (jacknet_packet_header); while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size)) { pkthdr->fragment_nr = htonl (frag_cnt++); memcpy (dataX, packet_bufX, fragment_payload_size); sendto (sockfd, tx_packet, mtu, flags, addr, addr_size); packet_bufX += fragment_payload_size; } int last_payload_size = packet_buf + pkt_size - packet_bufX; memcpy (dataX, packet_bufX, last_payload_size); pkthdr->fragment_nr = htonl (frag_cnt); //jack_log("last fragment_count = %d, payload_size = %d\n", fragment_count, last_payload_size); // sendto(last_pack_size); err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size); if( err < 0 ) { //printf( "error in send\n" ); perror( "send" ); } } } void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf) { int i; jack_midi_clear_buffer (buf); for (i = 0; i < buffer_size_uint32 - 3;) { uint32_t payload_size; payload_size = buffer_uint32[i]; payload_size = ntohl (payload_size); if (payload_size) { jack_midi_event_t event; event.time = ntohl (buffer_uint32[i + 1]); event.size = ntohl (buffer_uint32[i + 2]); event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i + 3])); jack_midi_event_write (buf, event.time, event.buffer, event.size); // skip to the next event unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1; i += 3 + nb_data_quads; } else break; // no events can follow an empty event, we're done } } void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf) { int i; unsigned int written = 0; // midi port, encode midi events unsigned int nevents = jack_midi_get_event_count (buf); for (i = 0; i < nevents; ++i) { jack_midi_event_t event; jack_midi_event_get (&event, buf, i); unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1; unsigned int payload_size = 3 + nb_data_quads; // only write if we have sufficient space for the event // otherwise drop it if (written + payload_size < buffer_size_uint32 - 1) { // write header buffer_uint32[written] = htonl (payload_size); written++; buffer_uint32[written] = htonl (event.time); written++; buffer_uint32[written] = htonl (event.size); written++; // write data jack_midi_data_t* tmpbuff = (jack_midi_data_t*)(&(buffer_uint32[written])); memcpy (tmpbuff, event.buffer, event.size); written += nb_data_quads; } else { // buffer overflow jack_error ("midi buffer overflow"); break; } } // now put a netjack_midi 'no-payload' event, signaling EOF buffer_uint32[written] = 0; } // render functions for float void render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) { int chn = 0; JSList *node = capture_ports; #if HAVE_SAMPLERATE JSList *src_node = capture_srcs; #endif uint32_t *packet_bufX = (uint32_t *)packet_payload; if (!packet_payload) return; while (node != NULL) { int i; int_float_t val; #if HAVE_SAMPLERATE SRC_DATA src; #endif jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { #if HAVE_SAMPLERATE // audio port, resample if necessary if (net_period_down != nframes) { SRC_STATE *src_state = src_node->data; for (i = 0; i < net_period_down; i++) { packet_bufX[i] = ntohl (packet_bufX[i]); } src.data_in = (float *) packet_bufX; src.input_frames = net_period_down; src.data_out = buf; src.output_frames = nframes; src.src_ratio = (float) nframes / (float) net_period_down; src.end_of_input = 0; src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); src_node = jack_slist_next (src_node); } else #endif { if( dont_htonl_floats ) { memcpy( buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t)); } else { for (i = 0; i < net_period_down; i++) { val.i = packet_bufX[i]; val.i = ntohl (val.i); buf[i] = val.f; } } } } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down; uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); chn++; } } void render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) { int chn = 0; JSList *node = playback_ports; #if HAVE_SAMPLERATE JSList *src_node = playback_srcs; #endif uint32_t *packet_bufX = (uint32_t *) packet_payload; while (node != NULL) { #if HAVE_SAMPLERATE SRC_DATA src; #endif int i; int_float_t val; jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { // audio port, resample if necessary #if HAVE_SAMPLERATE if (net_period_up != nframes) { SRC_STATE *src_state = src_node->data; src.data_in = buf; src.input_frames = nframes; src.data_out = (float *) packet_bufX; src.output_frames = net_period_up; src.src_ratio = (float) net_period_up / (float) nframes; src.end_of_input = 0; src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); for (i = 0; i < net_period_up; i++) { packet_bufX[i] = htonl (packet_bufX[i]); } src_node = jack_slist_next (src_node); } else #endif { if( dont_htonl_floats ) { memcpy( packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t) ); } else { for (i = 0; i < net_period_up; i++) { val.f = buf[i]; val.i = htonl (val.i); packet_bufX[i] = val.i; } } } } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_up); node = jack_slist_next (node); chn++; } } // render functions for 16bit void render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) { int chn = 0; JSList *node = capture_ports; #if HAVE_SAMPLERATE JSList *src_node = capture_srcs; #endif uint16_t *packet_bufX = (uint16_t *)packet_payload; if( !packet_payload ) return; while (node != NULL) { int i; //uint32_t val; #if HAVE_SAMPLERATE SRC_DATA src; #endif jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); #if HAVE_SAMPLERATE float *floatbuf = alloca (sizeof(float) * net_period_down); #endif const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { // audio port, resample if necessary #if HAVE_SAMPLERATE if (net_period_down != nframes) { SRC_STATE *src_state = src_node->data; for (i = 0; i < net_period_down; i++) { floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0; } src.data_in = floatbuf; src.input_frames = net_period_down; src.data_out = buf; src.output_frames = nframes; src.src_ratio = (float) nframes / (float) net_period_down; src.end_of_input = 0; src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); src_node = jack_slist_next (src_node); } else #endif for (i = 0; i < net_period_down; i++) buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0; } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); chn++; } } void render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) { int chn = 0; JSList *node = playback_ports; #if HAVE_SAMPLERATE JSList *src_node = playback_srcs; #endif uint16_t *packet_bufX = (uint16_t *)packet_payload; while (node != NULL) { #if HAVE_SAMPLERATE SRC_DATA src; #endif int i; jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { // audio port, resample if necessary #if HAVE_SAMPLERATE if (net_period_up != nframes) { SRC_STATE *src_state = src_node->data; float *floatbuf = alloca (sizeof(float) * net_period_up); src.data_in = buf; src.input_frames = nframes; src.data_out = floatbuf; src.output_frames = net_period_up; src.src_ratio = (float) net_period_up / (float) nframes; src.end_of_input = 0; src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); for (i = 0; i < net_period_up; i++) { packet_bufX[i] = htons (((uint16_t)((floatbuf[i] + 1.0) * 32767.0))); } src_node = jack_slist_next (src_node); } else #endif for (i = 0; i < net_period_up; i++) packet_bufX[i] = htons(((uint16_t)((buf[i] + 1.0) * 32767.0))); } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_up); node = jack_slist_next (node); chn++; } } // render functions for 8bit void render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) { int chn = 0; JSList *node = capture_ports; #if HAVE_SAMPLERATE JSList *src_node = capture_srcs; #endif int8_t *packet_bufX = (int8_t *)packet_payload; if (!packet_payload) return; while (node != NULL) { int i; //uint32_t val; #if HAVE_SAMPLERATE SRC_DATA src; #endif jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); #if HAVE_SAMPLERATE float *floatbuf = alloca (sizeof (float) * net_period_down); #endif const char *porttype = jack_port_type (port); if (jack_port_is_audio(porttype)) { #if HAVE_SAMPLERATE // audio port, resample if necessary if (net_period_down != nframes) { SRC_STATE *src_state = src_node->data; for (i = 0; i < net_period_down; i++) floatbuf[i] = ((float) packet_bufX[i]) / 127.0; src.data_in = floatbuf; src.input_frames = net_period_down; src.data_out = buf; src.output_frames = nframes; src.src_ratio = (float) nframes / (float) net_period_down; src.end_of_input = 0; src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); src_node = jack_slist_next (src_node); } else #endif for (i = 0; i < net_period_down; i++) buf[i] = ((float) packet_bufX[i]) / 127.0; } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); chn++; } } void render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) { int chn = 0; JSList *node = playback_ports; #if HAVE_SAMPLERATE JSList *src_node = playback_srcs; #endif int8_t *packet_bufX = (int8_t *)packet_payload; while (node != NULL) { #if HAVE_SAMPLERATE SRC_DATA src; #endif int i; jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { #if HAVE_SAMPLERATE // audio port, resample if necessary if (net_period_up != nframes) { SRC_STATE *src_state = src_node->data; float *floatbuf = alloca (sizeof (float) * net_period_up); src.data_in = buf; src.input_frames = nframes; src.data_out = floatbuf; src.output_frames = net_period_up; src.src_ratio = (float) net_period_up / (float) nframes; src.end_of_input = 0; src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); for (i = 0; i < net_period_up; i++) packet_bufX[i] = floatbuf[i] * 127.0; src_node = jack_slist_next (src_node); } else #endif for (i = 0; i < net_period_up; i++) packet_bufX[i] = buf[i] * 127.0; } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 4; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_up); node = jack_slist_next (node); chn++; } } #if HAVE_CELT // render functions for celt. void render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) { int chn = 0; JSList *node = capture_ports; JSList *src_node = capture_srcs; unsigned char *packet_bufX = (unsigned char *)packet_payload; while (node != NULL) { jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { // audio port, decode celt data. CELTDecoder *decoder = src_node->data; #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 if( !packet_payload ) celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); else celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); #else if( !packet_payload ) celt_decode_float( decoder, NULL, net_period_down, buf ); else celt_decode_float( decoder, packet_bufX, net_period_down, buf ); #endif src_node = jack_slist_next (src_node); } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; if( packet_payload ) decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); chn++; } } void render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) { int chn = 0; JSList *node = playback_ports; JSList *src_node = playback_srcs; unsigned char *packet_bufX = (unsigned char *)packet_payload; while (node != NULL) { jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { // audio port, encode celt data. int encoded_bytes; float *floatbuf = alloca (sizeof(float) * nframes ); memcpy( floatbuf, buf, nframes * sizeof(float) ); CELTEncoder *encoder = src_node->data; #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up ); #else encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); #endif if( encoded_bytes != net_period_up ) printf( "something in celt changed. netjack needs to be changed to handle this.\n" ); src_node = jack_slist_next( src_node ); } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_up); node = jack_slist_next (node); chn++; } } #endif #if HAVE_OPUS #define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length) // render functions for Opus. void render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) { int chn = 0; JSList *node = capture_ports; JSList *src_node = capture_srcs; unsigned char *packet_bufX = (unsigned char *)packet_payload; while (node != NULL) { jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { // audio port, decode opus data. OpusCustomDecoder *decoder = (OpusCustomDecoder*) src_node->data; if( !packet_payload ) memset(buf, 0, nframes * sizeof(float)); else { unsigned short len; memcpy(&len, packet_bufX, CDO); len = ntohs(len); opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes ); } src_node = jack_slist_next (src_node); } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; if( packet_payload ) decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); chn++; } } void render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) { int chn = 0; JSList *node = playback_ports; JSList *src_node = playback_srcs; unsigned char *packet_bufX = (unsigned char *)packet_payload; while (node != NULL) { jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); if (jack_port_is_audio (porttype)) { // audio port, encode opus data. int encoded_bytes; float *floatbuf = alloca (sizeof(float) * nframes ); memcpy( floatbuf, buf, nframes * sizeof(float) ); OpusCustomEncoder *encoder = (OpusCustomEncoder*) src_node->data; encoded_bytes = opus_custom_encode_float( encoder, floatbuf, nframes, packet_bufX + CDO, net_period_up - CDO ); unsigned short len = htons(encoded_bytes); memcpy(packet_bufX, &len, CDO); src_node = jack_slist_next( src_node ); } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_up); node = jack_slist_next (node); chn++; } } #endif /* Wrapper functions with bitdepth argument... */ void render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) { if (bitdepth == 8) render_payload_to_jack_ports_8bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); else if (bitdepth == 16) render_payload_to_jack_ports_16bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); #if HAVE_CELT else if (bitdepth == CELT_MODE) render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); #endif #if HAVE_OPUS else if (bitdepth == OPUS_MODE) render_payload_to_jack_ports_opus (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); #endif else render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); } void render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) { if (bitdepth == 8) render_jack_ports_to_payload_8bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); else if (bitdepth == 16) render_jack_ports_to_payload_16bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); #if HAVE_CELT else if (bitdepth == CELT_MODE) render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); #endif #if HAVE_OPUS else if (bitdepth == OPUS_MODE) render_jack_ports_to_payload_opus (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); #endif else render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); } 1.9.12~dfsg/common/JackLibAPI.cpp0000644000000000000000000001471113214314510015171 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackDebugClient.h" #include "JackLibClient.h" #include "JackChannel.h" #include "JackLibGlobals.h" #include "JackGlobals.h" #include "JackCompilerDeps.h" #include "JackTools.h" #include "JackSystemDeps.h" #include "JackServerLaunch.h" #include using namespace Jack; #ifdef __cplusplus extern "C" { #endif jack_client_t * jack_client_new_aux (const char *client_name, jack_options_t options, jack_status_t *status); LIB_EXPORT jack_client_t * jack_client_open (const char *client_name, jack_options_t options, jack_status_t *status, ...); LIB_EXPORT int jack_client_close (jack_client_t *client); LIB_EXPORT int jack_get_client_pid (const char *name); #ifdef __cplusplus } #endif static jack_client_t * jack_client_open_aux (const char *client_name, jack_options_t options, jack_status_t *status, va_list ap); JackLibGlobals* JackLibGlobals::fGlobals = NULL; int JackLibGlobals::fClientCount = 0; jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status) { jack_varargs_t va; /* variable arguments */ jack_status_t my_status; JackClient* client; if (client_name == NULL) { jack_error("jack_client_new called with a NULL client_name"); return NULL; } jack_log("jack_client_new %s", client_name); if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ *status = (jack_status_t)0; /* validate parameters */ if ((options & ~JackOpenOptions)) { int my_status1 = *status | (JackFailure | JackInvalidOption); *status = (jack_status_t)my_status1; return NULL; } /* parse variable arguments */ jack_varargs_init(&va); JackLibGlobals::Init(); // jack library initialisation if (try_start_server(&va, options, status)) { jack_error("jack server is not running or cannot be started"); JackLibGlobals::Destroy(); // jack library destruction return 0; } if (JACK_DEBUG) { client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode } else { client = new JackLibClient(GetSynchroTable()); } int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; JackLibGlobals::Destroy(); // jack library destruction int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } else { return (jack_client_t*)client; } } static jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) { jack_varargs_t va; /* variable arguments */ jack_status_t my_status; JackClient* client; if (client_name == NULL) { jack_error("jack_client_open called with a NULL client_name"); return NULL; } jack_log("jack_client_open %s", client_name); if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ *status = (jack_status_t)0; /* validate parameters */ if ((options & ~JackOpenOptions)) { int my_status1 = *status | (JackFailure | JackInvalidOption); *status = (jack_status_t)my_status1; return NULL; } /* parse variable arguments */ jack_varargs_parse(options, ap, &va); JackLibGlobals::Init(); // jack library initialisation if (try_start_server(&va, options, status)) { jack_error("jack server is not running or cannot be started"); JackLibGlobals::Destroy(); // jack library destruction return 0; } if (JACK_DEBUG) { client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode } else { client = new JackLibClient(GetSynchroTable()); } int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; JackLibGlobals::Destroy(); // jack library destruction int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } else { return (jack_client_t*)client; } } LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { JackGlobals::CheckContext("jack_client_open"); try { assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); va_list ap; va_start(ap, status); jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); va_end(ap); JackGlobals::fOpenMutex->Unlock(); return res; } catch (std::bad_alloc& e) { jack_error("Memory allocation error..."); return NULL; } catch (...) { jack_error("Unknown error..."); return NULL; } } LIB_EXPORT int jack_client_close(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_client_close"); assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); int res = -1; jack_log("jack_client_close"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_client_close called with a NULL client"); } else { res = client->Close(); delete client; JackLibGlobals::Destroy(); // jack library destruction jack_log("jack_client_close res = %d", res); } JackGlobals::fOpenMutex->Unlock(); return res; } LIB_EXPORT int jack_get_client_pid(const char *name) { jack_error("jack_get_client_pid : not implemented on library side"); return 0; } 1.9.12~dfsg/common/JackServerGlobals.cpp0000644000000000000000000003267713214314510016716 0ustar rootroot/* Copyright (C) 2005 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackServerGlobals.h" #include "JackLockedEngine.h" #include "JackTools.h" #include "shm.h" #include #include static char* server_name = NULL; namespace Jack { JackServer* JackServerGlobals::fInstance; unsigned int JackServerGlobals::fUserCount; std::map JackServerGlobals::fSlavesList; std::map JackServerGlobals::fInternalsList; bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL; int JackServerGlobals::Start(const char* server_name, jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, int temporary, int time_out_ms, int rt, int priority, int port_max, int verbose, jack_timer_type_t clock, char self_connect_mode) { jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, self_connect_mode, server_name); // Will setup fInstance and fUserCount globals int res = fInstance->Open(driver_desc, driver_params); return (res < 0) ? res : fInstance->Start(); } void JackServerGlobals::Stop() { jack_log("Jackdmp: server close"); fInstance->Stop(); fInstance->Close(); } void JackServerGlobals::Delete() { jack_log("Jackdmp: delete server"); // Slave drivers std::map::iterator it1; for (it1 = fSlavesList.begin(); it1 != fSlavesList.end(); it1++) { JackDriverInfo* info = (*it1).second; if (info) { fInstance->RemoveSlave((info)); delete (info); } } fSlavesList.clear(); // Internal clients std::map ::iterator it2; for (it2 = fInternalsList.begin(); it2 != fInternalsList.end(); it2++) { int status; int refnum = (*it2).second; if (refnum > 0) { // Client object is internally kept in JackEngine, and will be deallocated in InternalClientUnload fInstance->GetEngine()->InternalClientUnload(refnum, &status); } } fInternalsList.clear(); delete fInstance; fInstance = NULL; } bool JackServerGlobals::Init() { int realtime = 0; int client_timeout = 0; /* msecs; if zero, use period size. */ int realtime_priority = 10; int verbose_aux = 0; unsigned int port_max = 128; int temporary = 0; int opt = 0; int option_index = 0; char *master_driver_name = NULL; char **master_driver_args = NULL; JSList* master_driver_params = NULL; jack_driver_desc_t* driver_desc; jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK; int driver_nargs = 1; JSList* drivers = NULL; int loopback = 0; int sync = 0; int rc, i; int res; int replace_registry = 0; FILE* fp = 0; char filename[255]; char buffer[255]; int argc = 0; char* argv[32]; // First user starts the server if (fUserCount++ == 0) { jack_log("JackServerGlobals Init"); const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:" #ifdef __linux__ "c:" #endif ; struct option long_options[] = { #ifdef __linux__ { "clock-source", 1, 0, 'c' }, #endif { "loopback-driver", 1, 0, 'L' }, { "audio-driver", 1, 0, 'd' }, { "midi-driver", 1, 0, 'X' }, { "internal-client", 1, 0, 'I' }, { "verbose", 0, 0, 'v' }, { "help", 0, 0, 'h' }, { "port-max", 1, 0, 'p' }, { "no-mlock", 0, 0, 'm' }, { "name", 1, 0, 'n' }, { "unlock", 0, 0, 'u' }, { "realtime", 0, 0, 'R' }, { "no-realtime", 0, 0, 'r' }, { "replace-registry", 0, &replace_registry, 0 }, { "loopback", 0, 0, 'L' }, { "realtime-priority", 1, 0, 'P' }, { "timeout", 1, 0, 't' }, { "temporary", 0, 0, 'T' }, { "version", 0, 0, 'V' }, { "silent", 0, 0, 's' }, { "sync", 0, 0, 'S' }, { 0, 0, 0, 0 } }; snprintf(filename, 255, "%s/.jackdrc", getenv("HOME")); fp = fopen(filename, "r"); if (!fp) { fp = fopen("/etc/jackdrc", "r"); } // if still not found, check old config name for backwards compatability if (!fp) { fp = fopen("/etc/jackd.conf", "r"); } argc = 0; if (fp) { res = fscanf(fp, "%s", buffer); while (res != 0 && res != EOF) { argv[argc] = (char*)malloc(64); strcpy(argv[argc], buffer); res = fscanf(fp, "%s", buffer); argc++; } fclose(fp); } /* For testing int argc = 15; char* argv[] = {"jackdmp", "-R", "-v", "-d", "coreaudio", "-p", "512", "-d", "~:Aggregate:0", "-r", "48000", "-i", "2", "-o", "2" }; */ opterr = 0; optind = 1; // Important : to reset argv parsing while (!master_driver_name && (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { case 'c': if (tolower (optarg[0]) == 'h') { clock_source = JACK_TIMER_HPET; } else if (tolower (optarg[0]) == 'c') { /* For backwards compatibility with scripts, allow * the user to request the cycle clock on the * command line, but use the system clock instead */ clock_source = JACK_TIMER_SYSTEM_CLOCK; } else if (tolower (optarg[0]) == 's') { clock_source = JACK_TIMER_SYSTEM_CLOCK; } else { jack_error("unknown option character %c", optopt); } break; case 'd': master_driver_name = optarg; break; case 'L': loopback = atoi(optarg); break; case 'X': fSlavesList[optarg] = NULL; break; case 'I': fInternalsList[optarg] = -1; break; case 'p': port_max = (unsigned int)atol(optarg); break; case 'm': break; case 'u': break; case 'v': verbose_aux = 1; break; case 'S': sync = 1; break; case 'n': server_name = optarg; break; case 'P': realtime_priority = atoi(optarg); break; case 'r': realtime = 0; break; case 'R': realtime = 1; break; case 'T': temporary = 1; break; case 't': client_timeout = atoi(optarg); break; default: jack_error("unknown option character %c", optopt); break; } } drivers = jack_drivers_load(drivers); if (!drivers) { jack_error("jackdmp: no drivers found; exiting"); goto error; } driver_desc = jack_find_driver_descriptor(drivers, master_driver_name); if (!driver_desc) { jack_error("jackdmp: unknown master driver '%s'", master_driver_name); goto error; } if (optind < argc) { driver_nargs = 1 + argc - optind; } else { driver_nargs = 1; } if (driver_nargs == 0) { jack_error("No driver specified ... hmm. JACK won't do" " anything when run like this."); goto error; } master_driver_args = (char**)malloc(sizeof(char*) * driver_nargs); master_driver_args[0] = master_driver_name; for (i = 1; i < driver_nargs; i++) { master_driver_args[i] = argv[optind++]; } if (jack_parse_driver_params(driver_desc, driver_nargs, master_driver_args, &master_driver_params)) { goto error; } #ifndef WIN32 if (server_name == NULL) { server_name = (char*)JackTools::DefaultServerName(); } #endif rc = jack_register_server(server_name, false); switch (rc) { case EEXIST: jack_error("`%s' server already active", server_name); goto error; case ENOSPC: jack_error("too many servers already active"); goto error; case ENOMEM: jack_error("no access to shm registry"); goto error; default: jack_info("server `%s' registered", server_name); } /* clean up shared memory and files from any previous instance of this server name */ jack_cleanup_shm(); JackTools::CleanupFiles(server_name); if (!realtime && client_timeout == 0) { client_timeout = 500; /* 0.5 sec; usable when non realtime. */ } for (i = 0; i < argc; i++) { free(argv[i]); } int res = Start(server_name, driver_desc, master_driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source, JACK_DEFAULT_SELF_CONNECT_MODE); if (res < 0) { jack_error("Cannot start server... exit"); Delete(); jack_cleanup_shm(); JackTools::CleanupFiles(server_name); jack_unregister_server(server_name); goto error; } // Slave drivers std::map::iterator it1; for (it1 = fSlavesList.begin(); it1 != fSlavesList.end(); it1++) { const char* name = ((*it1).first).c_str(); driver_desc = jack_find_driver_descriptor(drivers, name); if (!driver_desc) { jack_error("jackdmp: unknown slave driver '%s'", name); } else { (*it1).second = fInstance->AddSlave(driver_desc, NULL); } } // Loopback driver if (loopback > 0) { driver_desc = jack_find_driver_descriptor(drivers, "loopback"); if (!driver_desc) { jack_error("jackdmp: unknown driver '%s'", "loopback"); } else { fSlavesList["loopback"] = fInstance->AddSlave(driver_desc, NULL); } } // Internal clients std::map::iterator it2; for (it2 = fInternalsList.begin(); it2 != fInternalsList.end(); it2++) { int status, refnum; const char* name = ((*it2).first).c_str(); fInstance->InternalClientLoad2(name, name, NULL, JackNullOption, &refnum, -1, &status); (*it2).second = refnum; } } if (master_driver_params) { jack_free_driver_params(master_driver_params); } return true; error: jack_log("JackServerGlobals Init error"); if (master_driver_params) { jack_free_driver_params(master_driver_params); } Destroy(); return false; } void JackServerGlobals::Destroy() { if (--fUserCount == 0) { jack_log("JackServerGlobals Destroy"); Stop(); Delete(); jack_cleanup_shm(); JackTools::CleanupFiles(server_name); jack_unregister_server(server_name); } } } // end of namespace 1.9.12~dfsg/common/JackNetAPI.cpp0000644000000000000000000012473213214314510015216 0ustar rootroot/* Copyright (C) 2009-2013 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "JackNetInterface.h" #include "JackAudioAdapterInterface.h" #ifdef __cplusplus extern "C" { #endif // NetJack common API #define MASTER_NAME_SIZE 256 enum JackNetEncoder { JackFloatEncoder = 0, JackIntEncoder = 1, JackCeltEncoder = 2, JackOpusEncoder = 3 }; typedef struct { int audio_input; int audio_output; int midi_input; int midi_output; int mtu; int time_out; // in millisecond, -1 means in infinite int encoder; // one of JackNetEncoder int kbps; // KB per second for CELT encoder int latency; // network cycles } jack_slave_t; typedef struct { int audio_input; int audio_output; int midi_input; int midi_output; jack_nframes_t buffer_size; jack_nframes_t sample_rate; char master_name[MASTER_NAME_SIZE]; int time_out; int partial_cycle; } jack_master_t; // NetJack slave API typedef struct _jack_net_slave jack_net_slave_t; typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, void* data); typedef int (*JackNetSlaveBufferSizeCallback) (jack_nframes_t nframes, void *arg); typedef int (*JackNetSlaveSampleRateCallback) (jack_nframes_t nframes, void *arg); typedef void (*JackNetSlaveShutdownCallback) (void* arg); typedef int (*JackNetSlaveRestartCallback) (void* arg); typedef void (*JackNetSlaveErrorCallback) (int error_code, void* arg); LIB_EXPORT jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result); LIB_EXPORT int jack_net_slave_close(jack_net_slave_t* net); LIB_EXPORT int jack_net_slave_activate(jack_net_slave_t* net); LIB_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net); LIB_EXPORT int jack_net_slave_is_active(jack_net_slave_t* net); LIB_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg); LIB_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t* net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg); LIB_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t* net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); LIB_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t* net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); LIB_EXPORT int jack_set_net_slave_restart_callback(jack_net_slave_t* net, JackNetSlaveRestartCallback restart_callback, void *arg); LIB_EXPORT int jack_set_net_slave_error_callback(jack_net_slave_t* net, JackNetSlaveErrorCallback error_callback, void *arg); // NetJack master API typedef struct _jack_net_master jack_net_master_t; LIB_EXPORT jack_net_master_t* jack_net_master_open(const char* ip, int port, jack_master_t* request, jack_slave_t* result); LIB_EXPORT int jack_net_master_close(jack_net_master_t* net); LIB_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); LIB_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); LIB_EXPORT int jack_net_master_recv_slice(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames); LIB_EXPORT int jack_net_master_send_slice(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames); // NetJack adapter API typedef struct _jack_adapter jack_adapter_t; LIB_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate); LIB_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter); LIB_EXPORT void jack_flush_adapter(jack_adapter_t* adapter); LIB_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); LIB_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); #define LOG_LEVEL_INFO 1 #define LOG_LEVEL_ERROR 2 LIB_EXPORT void jack_error(const char *fmt, ...); LIB_EXPORT void jack_info(const char *fmt, ...); LIB_EXPORT void jack_log(const char *fmt, ...); #ifdef __cplusplus } #endif namespace Jack { struct JackNetExtMaster : public JackNetMasterInterface { jack_master_t fRequest; JackRingBuffer** fRingBuffer; JackNetExtMaster(const char* ip, int port, jack_master_t* request) { fRunning = true; assert(strlen(ip) < 32); strcpy(fMulticastIP, ip); fSocket.SetPort(port); fRequest.buffer_size = request->buffer_size; fRequest.sample_rate = request->sample_rate; fRequest.audio_input = request->audio_input; fRequest.audio_output = request->audio_output; fRequest.time_out = request->time_out; fRequest.partial_cycle = request->partial_cycle; fRingBuffer = NULL; } virtual ~JackNetExtMaster() { if (fRingBuffer) { for (int i = 0; i < fParams.fReturnAudioChannels; i++) { delete fRingBuffer[i]; } delete [] fRingBuffer; } } int Open(jack_slave_t* result) { // Check buffer_size if (fRequest.buffer_size == 0) { jack_error("Incorrect buffer_size..."); return -1; } // Check sample_rate if (fRequest.sample_rate == 0) { jack_error("Incorrect sample_rate..."); return -1; } // Init socket API (win32) if (SocketAPIInit() < 0) { jack_error("Can't init Socket API, exiting..."); return -1; } // Request socket if (fSocket.NewSocket() == SOCKET_ERROR) { jack_error("Can't create the network manager input socket : %s", StrError(NET_ERROR_CODE)); return -1; } // Bind the socket to the local port if (fSocket.Bind() == SOCKET_ERROR) { jack_error("Can't bind the network manager socket : %s", StrError(NET_ERROR_CODE)); fSocket.Close(); return -1; } // Join multicast group if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) { jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE)); } // Local loop if (fSocket.SetLocalLoop() == SOCKET_ERROR) { jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE)); } // Set a timeout on the multicast receive (the thread can now be cancelled) if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) { jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE)); } // Main loop, wait for data, deal with it and wait again int attempt = 0; int rx_bytes = 0; int try_count = (fRequest.time_out > 0) ? int((1000000.f * float(fRequest.time_out)) / float(MANAGER_INIT_TIMEOUT)) : INT_MAX; do { session_params_t net_params; rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0); SessionParamsNToH(&net_params, &fParams); if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { jack_error("Error in receive : %s", StrError(NET_ERROR_CODE)); if (++attempt == 10) { jack_error("Can't receive on the socket, exiting net manager" ); goto error; } } if (rx_bytes == sizeof(session_params_t)) { switch (GetPacketType(&fParams)) { case SLAVE_AVAILABLE: if (InitMaster(result) == 0) { SessionParamsDisplay(&fParams); fRunning = false; } else { jack_error("Can't init new net master..."); goto error; } jack_info("Waiting for a slave..."); break; case KILL_MASTER: break; default: break; } } } while (fRunning && (--try_count > 0)); if (try_count == 0) { jack_error("Time out error in connect"); return -1; } // Set result parameters result->audio_input = fParams.fSendAudioChannels; result->audio_output = fParams.fReturnAudioChannels; result->midi_input = fParams.fSendMidiChannels; result->midi_output = fParams.fReturnMidiChannels; result->mtu = fParams.fMtu; result->latency = fParams.fNetworkLatency; // Use ringbuffer in case of partial cycle and latency > 0 if (fRequest.partial_cycle && result->latency > 0) { fRingBuffer = new JackRingBuffer*[fParams.fReturnAudioChannels]; for (int i = 0; i < fParams.fReturnAudioChannels; i++) { fRingBuffer[i] = new JackRingBuffer(fRequest.buffer_size * result->latency * 2); } } return 0; error: fSocket.Close(); return -1; } int InitMaster(jack_slave_t* result) { // Check MASTER <==> SLAVE network protocol coherency if (fParams.fProtocolVersion != NETWORK_PROTOCOL) { jack_error("Error : slave '%s' is running with a different protocol %d != %d", fParams.fName, fParams.fProtocolVersion, NETWORK_PROTOCOL); return -1; } // Settings fSocket.GetName(fParams.fMasterNetName); fParams.fID = 1; fParams.fPeriodSize = fRequest.buffer_size; fParams.fSampleRate = fRequest.sample_rate; if (fRequest.audio_input == -1) { if (fParams.fSendAudioChannels == -1) { jack_error("Error : master and slave use -1 for wanted inputs..."); return -1; } else { result->audio_input = fParams.fSendAudioChannels; jack_info("Takes slave %d inputs", fParams.fSendAudioChannels); } } else if (fParams.fSendAudioChannels == -1) { fParams.fSendAudioChannels = fRequest.audio_input; jack_info("Takes master %d inputs", fRequest.audio_input); } else if (fParams.fSendAudioChannels != fRequest.audio_input) { jack_error("Error : master wants %d inputs and slave wants %d inputs...", fRequest.audio_input, fParams.fSendAudioChannels); return -1; } if (fRequest.audio_output == -1) { if (fParams.fReturnAudioChannels == -1) { jack_error("Error : master and slave use -1 for wanted outputs..."); return -1; } else { result->audio_output = fParams.fReturnAudioChannels; jack_info("Takes slave %d outputs", fParams.fReturnAudioChannels); } } else if (fParams.fReturnAudioChannels == -1) { fParams.fReturnAudioChannels = fRequest.audio_output; jack_info("Takes master %d outputs", fRequest.audio_output); } else if (fParams.fReturnAudioChannels != fRequest.audio_output) { jack_error("Error : master wants %d outputs and slave wants %d outputs...", fRequest.audio_output, fParams.fReturnAudioChannels); return -1; } // Close request socket fSocket.Close(); /// Network init if (!JackNetMasterInterface::Init()) { return -1; } // Set global parameters if (!SetParams()) { return -1; } return 0; } int Close() { fSocket.Close(); return 0; } void UseRingBuffer(int audio_input, float** audio_input_buffer, int write, int read) { // Possibly use ringbuffer... if (fRingBuffer) { for (int i = 0; i < audio_input; i++) { fRingBuffer[i]->Write(audio_input_buffer[i], write); fRingBuffer[i]->Read(audio_input_buffer[i], read); } } } int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames) { try { // frames = -1 means : entire buffer if (frames < 0) frames = fParams.fPeriodSize; int read_frames = 0; assert(audio_input == fParams.fReturnAudioChannels); for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) { assert(audio_input_buffer[audio_port_index]); fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, audio_input_buffer[audio_port_index]); } for (int midi_port_index = 0; midi_port_index < midi_input; midi_port_index++) { assert(((JackMidiBuffer**)midi_input_buffer)[midi_port_index]); fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]); } int res1 = SyncRecv(); switch (res1) { case NET_SYNCHING: // Data will not be received, so cleanup buffers... for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) { memset(audio_input_buffer[audio_port_index], 0, sizeof(float) * fParams.fPeriodSize); } UseRingBuffer(audio_input, audio_input_buffer, fParams.fPeriodSize, frames); return res1; case SOCKET_ERROR: return res1; case SYNC_PACKET_ERROR: // since sync packet is incorrect, don't decode it and continue with data break; default: // decode sync DecodeSyncPacket(read_frames); break; } int res2 = DataRecv(); UseRingBuffer(audio_input, audio_input_buffer, read_frames, frames); return res2; } catch (JackNetException& e) { jack_error(e.what()); return -1; } } int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames) { try { // frames = -1 means : entire buffer if (frames < 0) frames = fParams.fPeriodSize; assert(audio_output == fParams.fSendAudioChannels); for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) { assert(audio_output_buffer[audio_port_index]); fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]); } for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) { assert(((JackMidiBuffer**)midi_output_buffer)[midi_port_index]); fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]); } EncodeSyncPacket(frames); // send sync if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; } // send data if (DataSend() == SOCKET_ERROR) { return SOCKET_ERROR; } return 0; } catch (JackNetException& e) { jack_error(e.what()); return -1; } } // Transport void EncodeTransportData() {} void DecodeTransportData() {} }; struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterface { // Data buffers float** fAudioCaptureBuffer; float** fAudioPlaybackBuffer; JackMidiBuffer** fMidiCaptureBuffer; JackMidiBuffer** fMidiPlaybackBuffer; JackThread fThread; JackNetSlaveProcessCallback fProcessCallback; void* fProcessArg; JackNetSlaveShutdownCallback fShutdownCallback; void* fShutdownArg; JackNetSlaveRestartCallback fRestartCallback; void* fRestartArg; JackNetSlaveErrorCallback fErrorCallback; void* fErrorArg; JackNetSlaveBufferSizeCallback fBufferSizeCallback; void* fBufferSizeArg; JackNetSlaveSampleRateCallback fSampleRateCallback; void* fSampleRateArg; int fConnectTimeOut; int fFrames; JackNetExtSlave(const char* ip, int port, const char* name, jack_slave_t* request) :fThread(this), fProcessCallback(NULL),fProcessArg(NULL), fShutdownCallback(NULL), fShutdownArg(NULL), fRestartCallback(NULL), fRestartArg(NULL), fErrorCallback(NULL), fErrorArg(NULL), fBufferSizeCallback(NULL), fBufferSizeArg(NULL), fSampleRateCallback(NULL), fSampleRateArg(NULL) { char host_name[JACK_CLIENT_NAME_SIZE + 1]; // Request parameters assert(strlen(ip) < 32); strcpy(fMulticastIP, ip); fParams.fMtu = request->mtu; fParams.fTransportSync = 0; fParams.fSendAudioChannels = request->audio_input; fParams.fReturnAudioChannels = request->audio_output; fParams.fSendMidiChannels = request->midi_input; fParams.fReturnMidiChannels = request->midi_output; fParams.fNetworkLatency = request->latency; fParams.fSampleEncoder = request->encoder; fParams.fKBps = request->kbps; fParams.fSlaveSyncMode = 1; fConnectTimeOut = request->time_out; // Create name with hostname and client name GetHostName(host_name, JACK_CLIENT_NAME_SIZE); snprintf(fParams.fName, JACK_CLIENT_NAME_SIZE, "%s_%s", host_name, name); fSocket.GetName(fParams.fSlaveNetName); // Set the socket parameters fSocket.SetPort(port); fSocket.SetAddress(fMulticastIP, port); fAudioCaptureBuffer = NULL; fAudioPlaybackBuffer = NULL; fMidiCaptureBuffer = NULL; fMidiPlaybackBuffer = NULL; } virtual ~JackNetExtSlave() {} void AllocPorts() { // Set buffers if (fParams.fSendAudioChannels > 0) { fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels]; for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize]; memset(fAudioCaptureBuffer[audio_port_index], 0, sizeof(float) * fParams.fPeriodSize); fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]); } } if (fParams.fSendMidiChannels > 0) { fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; memset(fMidiCaptureBuffer[midi_port_index], 0, sizeof(float) * fParams.fPeriodSize); fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]); } } if (fParams.fReturnAudioChannels > 0) { fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels]; for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) { fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize]; memset(fAudioPlaybackBuffer[audio_port_index], 0, sizeof(float) * fParams.fPeriodSize); fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]); } } if (fParams.fReturnMidiChannels > 0) { fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; memset(fMidiPlaybackBuffer[midi_port_index], 0, sizeof(float) * fParams.fPeriodSize); fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]); } } } void FreePorts() { if (fAudioCaptureBuffer) { for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { delete[] fAudioCaptureBuffer[audio_port_index]; } delete[] fAudioCaptureBuffer; fAudioCaptureBuffer = NULL; } if (fMidiCaptureBuffer) { for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { delete[] fMidiCaptureBuffer[midi_port_index]; } delete[] fMidiCaptureBuffer; fMidiCaptureBuffer = NULL; } if (fAudioPlaybackBuffer) { for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) { delete[] fAudioPlaybackBuffer[audio_port_index]; } delete[] fAudioPlaybackBuffer; fAudioPlaybackBuffer = NULL; } if (fMidiPlaybackBuffer) { for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { delete[] (fMidiPlaybackBuffer[midi_port_index]); } delete[] fMidiPlaybackBuffer; fMidiPlaybackBuffer = NULL; } } int Open(jack_master_t* result) { // Check audio/midi parameters if (fParams.fSendAudioChannels == 0 && fParams.fReturnAudioChannels == 0 && fParams.fSendMidiChannels == 0 && fParams.fReturnMidiChannels == 0) { jack_error("Incorrect audio/midi channels number..."); return -1; } // Check MTU parameters if ((fParams.fMtu < DEFAULT_MTU) && (fParams.fMtu > MAX_MTU)) { jack_error("MTU is not in the expected range [%d ... %d]", DEFAULT_MTU, MAX_MTU); return -1; } // Check CELT encoder parameters if ((fParams.fSampleEncoder == JackCeltEncoder) && (fParams.fKBps == 0)) { jack_error("CELT encoder with 0 for kps..."); return -1; } if ((fParams.fSampleEncoder == JackOpusEncoder) && (fParams.fKBps == 0)) { jack_error("Opus encoder with 0 for kps..."); return -1; } // Check latency if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) { jack_error("Network latency is limited to %d", NETWORK_MAX_LATENCY); return -1; } // Init network connection if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) { jack_error("Initing network fails..."); return -1; } // Finish connection... if (!JackNetSlaveInterface::InitRendering()) { jack_error("Starting network fails..."); return -1; } // Then set global parameters if (!SetParams()) { jack_error("SetParams error..."); return -1; } // Set result if (result != NULL) { result->buffer_size = fParams.fPeriodSize; result->sample_rate = fParams.fSampleRate; result->audio_input = fParams.fSendAudioChannels; result->audio_output = fParams.fReturnAudioChannels; result->midi_input = fParams.fSendMidiChannels; result->midi_output = fParams.fReturnMidiChannels; strcpy(result->master_name, fParams.fMasterNetName); } // By default fFrames is fPeriodSize fFrames = fParams.fPeriodSize; SessionParamsDisplay(&fParams); AllocPorts(); return 0; } int Restart() { // Do it until client possibly decides to stop trying to connect... while (true) { // If restart cb is set, then call it if (fRestartCallback) { if (fRestartCallback(fRestartArg) != 0) { return -1; } // Otherwise if shutdown cb is set, then call it } else if (fShutdownCallback) { fShutdownCallback(fShutdownArg); } // Init network connection if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) { jack_error("Initing network fails after time_out, retry..."); } else { break; } } // Finish connection if (!JackNetSlaveInterface::InitRendering()) { jack_error("Starting network fails..."); return -1; } // Then set global parameters if (!SetParams()) { jack_error("SetParams error..."); return -1; } // We need to notify possibly new buffer size and sample rate (see Execute) if (fBufferSizeCallback) { if (fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg) != 0) { jack_error("New buffer size = %d cannot be used...", fParams.fPeriodSize); return -1; } } if (fSampleRateCallback) { if (fSampleRateCallback(fParams.fSampleRate, fSampleRateArg) != 0) { jack_error("New sample rate = %d cannot be used...", fParams.fSampleRate); return -1; } } AllocPorts(); return 0; } int Close() { fSocket.Close(); FreePorts(); return 0; } // Transport void EncodeTransportData() {} void DecodeTransportData() {} bool Init() { // Will do "something" on OSX only... UInt64 period, constraint; period = constraint = UInt64(1000000000.f * (float(fParams.fPeriodSize) / float(fParams.fSampleRate))); UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize) * 1000; fThread.SetParams(period, computation, constraint); return (fThread.AcquireSelfRealTime(80) == 0); // TODO: get a value from the server } bool IsRunning() { return (fThread.GetStatus() == JackThread::kRunning); } bool Execute() { try { /* Fist cycle use an INT_MAX time out, so that connection is considered established (with PACKET_TIMEOUT later on) when the first cycle has been done. */ DummyProcess(); // keep running even in case of error while (fThread.GetStatus() == JackThread::kRunning) { if (Process() == SOCKET_ERROR) { return false; } } return false; } catch (JackNetException& e) { // otherwise just restart... e.PrintMessage(); jack_info("NetSlave is restarted"); fThread.DropRealTime(); fThread.SetStatus(JackThread::kIniting); FreePorts(); if (Restart() == 0 && Init()) { fThread.SetStatus(JackThread::kRunning); return true; } else { return false; } } } int Read() { // receive sync (launch the cycle) switch (SyncRecv()) { case SOCKET_ERROR: return SOCKET_ERROR; case SYNC_PACKET_ERROR: // since sync packet is incorrect, don't decode it and continue with data if (fErrorCallback) { fErrorCallback(SYNC_PACKET_ERROR, fErrorArg); } break; default: // decode sync DecodeSyncPacket(fFrames); break; } int res = DataRecv(); if (res == DATA_PACKET_ERROR && fErrorCallback) { fErrorCallback(DATA_PACKET_ERROR, fErrorArg); } return res; } int Write() { EncodeSyncPacket(fFrames); if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; } return DataSend(); } void DummyProcess() { // First cycle with INT_MAX time out SetPacketTimeOut(INT_MAX); // One cycle Process(); // Then use PACKET_TIMEOUT * fParams.fNetworkLatency for next cycles SetPacketTimeOut(std::max(int(PACKET_TIMEOUT), int(PACKET_TIMEOUT * fParams.fNetworkLatency))); } int Process() { // Read data from the network, throw JackNetException in case of network error... if (Read() == SOCKET_ERROR) { return SOCKET_ERROR; } if (fFrames < 0) fFrames = fParams.fPeriodSize; fProcessCallback(fFrames, fParams.fSendAudioChannels, fAudioCaptureBuffer, fParams.fSendMidiChannels, (void**)fMidiCaptureBuffer, fParams.fReturnAudioChannels, fAudioPlaybackBuffer, fParams.fReturnMidiChannels, (void**)fMidiPlaybackBuffer, fProcessArg); // Then write data to network, throw JackNetException in case of network error... if (Write() == SOCKET_ERROR) { return SOCKET_ERROR; } return 0; } int Start() { return (fProcessCallback == 0) ? -1 : fThread.StartSync(); } int Stop() { return (fProcessCallback == 0) ? -1 : fThread.Kill(); } // Callback int SetProcessCallback(JackNetSlaveProcessCallback net_callback, void *arg) { if (fThread.GetStatus() == JackThread::kRunning) { return -1; } else { fProcessCallback = net_callback; fProcessArg = arg; return 0; } } int SetShutdownCallback(JackNetSlaveShutdownCallback shutdown_callback, void *arg) { if (fThread.GetStatus() == JackThread::kRunning) { return -1; } else { fShutdownCallback = shutdown_callback; fShutdownArg = arg; return 0; } } int SetRestartCallback(JackNetSlaveRestartCallback restart_callback, void *arg) { if (fThread.GetStatus() == JackThread::kRunning) { return -1; } else { fRestartCallback = restart_callback; fRestartArg = arg; return 0; } } int SetErrorCallback(JackNetSlaveErrorCallback error_callback, void *arg) { if (fThread.GetStatus() == JackThread::kRunning) { return -1; } else { fErrorCallback = error_callback; fErrorArg = arg; return 0; } } int SetBufferSizeCallback(JackNetSlaveBufferSizeCallback bufsize_callback, void *arg) { if (fThread.GetStatus() == JackThread::kRunning) { return -1; } else { fBufferSizeCallback = bufsize_callback; fBufferSizeArg = arg; return 0; } } int SetSampleRateCallback(JackNetSlaveSampleRateCallback samplerate_callback, void *arg) { if (fThread.GetStatus() == JackThread::kRunning) { return -1; } else { fSampleRateCallback = samplerate_callback; fSampleRateArg = arg; return 0; } } }; struct JackNetAdapter : public JackAudioAdapterInterface { JackNetAdapter(int input, int output, jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate) :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate) { fCaptureChannels = input; fPlaybackChannels = output; Create(); } void Create() { //ringbuffers if (fCaptureChannels > 0) { fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; } if (fPlaybackChannels > 0) { fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; } if (fAdaptative) { AdaptRingBufferSize(); jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); } else { if (fRingbufferCurSize > DEFAULT_RB_SIZE) { fRingbufferCurSize = DEFAULT_RB_SIZE; } jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); } for (int i = 0; i < fCaptureChannels; i++ ) { fCaptureRingBuffer[i] = new JackResampler(); fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); } for (int i = 0; i < fPlaybackChannels; i++ ) { fPlaybackRingBuffer[i] = new JackResampler(); fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); } if (fCaptureChannels > 0) { jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); } if (fPlaybackChannels > 0) { jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); } } virtual ~JackNetAdapter() { Destroy(); } void Flush() { for (int i = 0; i < fCaptureChannels; i++ ) { fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); } for (int i = 0; i < fPlaybackChannels; i++ ) { fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); } } }; } // end of namespace using namespace Jack; LIB_EXPORT jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result) { JackNetExtSlave* slave = new JackNetExtSlave(ip, port, name, request); if (slave->Open(result) == 0) { return (jack_net_slave_t*)slave; } else { delete slave; return NULL; } } LIB_EXPORT int jack_net_slave_close(jack_net_slave_t* net) { JackNetExtSlave* slave = (JackNetExtSlave*)net; slave->Close(); delete slave; return 0; } LIB_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->SetProcessCallback(net_callback, arg); } LIB_EXPORT int jack_net_slave_activate(jack_net_slave_t* net) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->Start(); } LIB_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->Stop(); } LIB_EXPORT int jack_net_slave_is_active(jack_net_slave_t* net) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->IsRunning(); } LIB_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->SetBufferSizeCallback(bufsize_callback, arg); } LIB_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->SetSampleRateCallback(samplerate_callback, arg); } LIB_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->SetShutdownCallback(shutdown_callback, arg); } LIB_EXPORT int jack_set_net_slave_restart_callback(jack_net_slave_t *net, JackNetSlaveRestartCallback restart_callback, void *arg) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->SetRestartCallback(restart_callback, arg); } LIB_EXPORT int jack_set_net_slave_error_callback(jack_net_slave_t *net, JackNetSlaveErrorCallback error_callback, void *arg) { JackNetExtSlave* slave = (JackNetExtSlave*)net; return slave->SetErrorCallback(error_callback, arg); } // Master API LIB_EXPORT jack_net_master_t* jack_net_master_open(const char* ip, int port, jack_master_t* request, jack_slave_t* result) { JackNetExtMaster* master = new JackNetExtMaster(ip, port, request); if (master->Open(result) == 0) { return (jack_net_master_t*)master; } else { delete master; return NULL; } } LIB_EXPORT int jack_net_master_close(jack_net_master_t* net) { JackNetExtMaster* master = (JackNetExtMaster*)net; master->Close(); delete master; return 0; } LIB_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) { JackNetExtMaster* master = (JackNetExtMaster*)net; return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer, -1); } LIB_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) { JackNetExtMaster* master = (JackNetExtMaster*)net; return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer, -1); } LIB_EXPORT int jack_net_master_recv_slice(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames) { JackNetExtMaster* master = (JackNetExtMaster*)net; return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer, frames); } LIB_EXPORT int jack_net_master_send_slice(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames) { JackNetExtMaster* master = (JackNetExtMaster*)net; return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer, frames); } // Adapter API LIB_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate) { try { return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate); } catch (...) { return NULL; } } LIB_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) { delete((JackNetAdapter*)adapter); return 0; } LIB_EXPORT void jack_flush_adapter(jack_adapter_t* adapter) { JackNetAdapter* slave = (JackNetAdapter*)adapter; slave->Flush(); } LIB_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) { JackNetAdapter* slave = (JackNetAdapter*)adapter; return slave->PushAndPull(input, output, frames); } LIB_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) { JackNetAdapter* slave = (JackNetAdapter*)adapter; return slave->PullAndPush(input, output, frames); } static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) { static const char* netjack_log = getenv("JACK_NETJACK_LOG"); static bool is_netjack_log = (netjack_log) ? atoi(netjack_log) : 0; if (is_netjack_log) { char buffer[300]; size_t len; if (prefix != NULL) { len = strlen(prefix); memcpy(buffer, prefix, len); } else { len = 0; } vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap); printf("%s", buffer); printf("\n"); } } LIB_EXPORT void jack_error(const char *fmt, ...) { va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); va_end(ap); } LIB_EXPORT void jack_info(const char *fmt, ...) { va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); va_end(ap); } LIB_EXPORT void jack_log(const char *fmt, ...) { va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); va_end(ap); } 1.9.12~dfsg/common/JackMetadata.h0000644000000000000000000000314113214314510015311 0ustar rootroot/* Copyright (C) 2011 David Robillard Copyright (C) 2013 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_metadata_int_h__ #define __jack_metadata_int_h__ #include #ifdef __cplusplus extern "C" { #endif typedef struct { const char* key; const char* data; const char* type; } jack_property_t; typedef struct { jack_uuid_t subject; uint32_t property_cnt; jack_property_t* properties; uint32_t property_size; } jack_description_t; typedef enum { PropertyCreated, PropertyChanged, PropertyDeleted } jack_property_change_t; typedef void (*JackPropertyChangeCallback)(jack_uuid_t subject, const char* key, jack_property_change_t change, void* arg); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/common/JackMidiWriteQueue.cpp0000644000000000000000000000154413214314510017033 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMidiWriteQueue.h" using Jack::JackMidiWriteQueue; JackMidiWriteQueue::~JackMidiWriteQueue() { // Empty } 1.9.12~dfsg/common/timestamps.h0000644000000000000000000000220013214314510015161 0ustar rootroot/* Copyright (C) 2002 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_timestamps_h__ #define __jack_timestamps_h__ #include #ifdef __cplusplus extern "C" { #endif void jack_init_timestamps (unsigned long howmany); void jack_timestamp (const char *what); void jack_dump_timestamps (FILE *out); void jack_reset_timestamps (); #ifdef __cplusplus } #endif #endif /* __jack_timestamps_h__ */ 1.9.12~dfsg/common/JackNetTool.cpp0000644000000000000000000015001113214314510015507 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackNetTool.h" #include "JackError.h" #ifdef __APPLE__ #include class HardwareClock { public: HardwareClock(); void Reset(); void Update(); float GetDeltaTime() const; double GetTime() const; private: double m_clockToSeconds; uint64_t m_startAbsTime; uint64_t m_lastAbsTime; double m_time; float m_deltaTime; }; HardwareClock::HardwareClock() { mach_timebase_info_data_t info; mach_timebase_info(&info); m_clockToSeconds = (double)info.numer/info.denom/1000000000.0; Reset(); } void HardwareClock::Reset() { m_startAbsTime = mach_absolute_time(); m_lastAbsTime = m_startAbsTime; m_time = m_startAbsTime*m_clockToSeconds; m_deltaTime = 1.0f/60.0f; } void HardwareClock::Update() { const uint64_t currentTime = mach_absolute_time(); const uint64_t dt = currentTime - m_lastAbsTime; m_time = currentTime*m_clockToSeconds; m_deltaTime = (double)dt*m_clockToSeconds; m_lastAbsTime = currentTime; } float HardwareClock::GetDeltaTime() const { return m_deltaTime; } double HardwareClock::GetTime() const { return m_time; } #endif using namespace std; namespace Jack { // NetMidiBuffer********************************************************************************** NetMidiBuffer::NetMidiBuffer(session_params_t* params, uint32_t nports, char* net_buffer) { fNPorts = nports; fMaxBufsize = fNPorts * sizeof(sample_t) * params->fPeriodSize; fMaxPcktSize = params->fMtu - sizeof(packet_header_t); fBuffer = new char[fMaxBufsize]; fPortBuffer = new JackMidiBuffer* [fNPorts]; for (int port_index = 0; port_index < fNPorts; port_index++) { fPortBuffer[port_index] = NULL; } fNetBuffer = net_buffer; fCycleBytesSize = params->fMtu * (max(params->fSendMidiChannels, params->fReturnMidiChannels) * params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t))); } NetMidiBuffer::~NetMidiBuffer() { delete[] fBuffer; delete[] fPortBuffer; } size_t NetMidiBuffer::GetCycleSize() { return fCycleBytesSize; } int NetMidiBuffer::GetNumPackets(int data_size, int max_size) { int res1 = data_size % max_size; int res2 = data_size / max_size; return (res1) ? res2 + 1 : res2; } void NetMidiBuffer::SetBuffer(int index, JackMidiBuffer* buffer) { fPortBuffer[index] = buffer; } JackMidiBuffer* NetMidiBuffer::GetBuffer(int index) { return fPortBuffer[index]; } void NetMidiBuffer::DisplayEvents() { for (int port_index = 0; port_index < fNPorts; port_index++) { for (uint event = 0; event < fPortBuffer[port_index]->event_count; event++) { if (fPortBuffer[port_index]->IsValid()) { jack_info("port %d : midi event %u/%u -> time : %u, size : %u", port_index + 1, event + 1, fPortBuffer[port_index]->event_count, fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size); } } } } int NetMidiBuffer::RenderFromJackPorts() { int pos = 0; size_t copy_size; for (int port_index = 0; port_index < fNPorts; port_index++) { char* write_pos = fBuffer + pos; copy_size = sizeof(JackMidiBuffer) + fPortBuffer[port_index]->event_count * sizeof(JackMidiEvent); memcpy(fBuffer + pos, fPortBuffer[port_index], copy_size); pos += copy_size; memcpy(fBuffer + pos, fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos), fPortBuffer[port_index]->write_pos); pos += fPortBuffer[port_index]->write_pos; JackMidiBuffer* midi_buffer = reinterpret_cast(write_pos); MidiBufferHToN(midi_buffer, midi_buffer); } return pos; } void NetMidiBuffer::RenderToJackPorts() { int pos = 0; size_t copy_size; for (int port_index = 0; port_index < fNPorts; port_index++) { JackMidiBuffer* midi_buffer = reinterpret_cast(fBuffer + pos); MidiBufferNToH(midi_buffer, midi_buffer); copy_size = sizeof(JackMidiBuffer) + reinterpret_cast(fBuffer + pos)->event_count * sizeof(JackMidiEvent); memcpy(fPortBuffer[port_index], fBuffer + pos, copy_size); pos += copy_size; memcpy(fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos), fBuffer + pos, fPortBuffer[port_index]->write_pos); pos += fPortBuffer[port_index]->write_pos; } } void NetMidiBuffer::RenderFromNetwork(int sub_cycle, size_t copy_size) { memcpy(fBuffer + sub_cycle * fMaxPcktSize, fNetBuffer, copy_size); } int NetMidiBuffer::RenderToNetwork(int sub_cycle, size_t total_size) { int size = total_size - sub_cycle * fMaxPcktSize; int copy_size = (size <= fMaxPcktSize) ? size : fMaxPcktSize; memcpy(fNetBuffer, fBuffer + sub_cycle * fMaxPcktSize, copy_size); return copy_size; } // net audio buffer ********************************************************************************* NetAudioBuffer::NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer) { fNPorts = nports; fNetBuffer = net_buffer; fNumPackets = 0; fPortBuffer = new sample_t*[fNPorts]; fConnectedPorts = new bool[fNPorts]; for (int port_index = 0; port_index < fNPorts; port_index++) { fPortBuffer[port_index] = NULL; fConnectedPorts[port_index] = true; } fLastSubCycle = 0; fPeriodSize = 0; fSubPeriodSize = 0; fSubPeriodBytesSize = 0; fCycleDuration = 0.f; fCycleBytesSize = 0; } NetAudioBuffer::~NetAudioBuffer() { delete [] fConnectedPorts; delete [] fPortBuffer; } void NetAudioBuffer::SetBuffer(int index, sample_t* buffer) { fPortBuffer[index] = buffer; } sample_t* NetAudioBuffer::GetBuffer(int index) { return fPortBuffer[index]; } int NetAudioBuffer::CheckPacket(int cycle, int sub_cycle) { int res; if (sub_cycle != fLastSubCycle + 1) { jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle); res = DATA_PACKET_ERROR; } else { res = 0; } fLastSubCycle = sub_cycle; return res; } void NetAudioBuffer::NextCycle() { // reset for next cycle fLastSubCycle = -1; } void NetAudioBuffer::Cleanup() { for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { memset(fPortBuffer[port_index], 0, fPeriodSize * sizeof(sample_t)); } } } //network<->buffer int NetAudioBuffer::ActivePortsToNetwork(char* net_buffer) { int active_ports = 0; int* active_port_address = (int*)net_buffer; for (int port_index = 0; port_index < fNPorts; port_index++) { // Write the active port number if (fPortBuffer[port_index]) { *active_port_address = htonl(port_index); active_port_address++; active_ports++; assert(active_ports < 256); } } return active_ports; } void NetAudioBuffer::ActivePortsFromNetwork(char* net_buffer, uint32_t port_num) { int* active_port_address = (int*)net_buffer; for (int port_index = 0; port_index < fNPorts; port_index++) { fConnectedPorts[port_index] = false; } for (uint port_index = 0; port_index < port_num; port_index++) { int active_port = ntohl(*active_port_address); assert(active_port < fNPorts); fConnectedPorts[active_port] = true; active_port_address++; } } int NetAudioBuffer::RenderFromJackPorts(int unused_frames) { // Count active ports int active_ports = 0; for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { active_ports++; } } return active_ports; } void NetAudioBuffer::RenderToJackPorts(int unused_frames) { // Nothing to do NextCycle(); } // Float converter NetFloatAudioBuffer::NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer) : NetAudioBuffer(params, nports, net_buffer) { fPeriodSize = params->fPeriodSize; fPacketSize = PACKET_AVAILABLE_SIZE(params); UpdateParams(max(params->fReturnAudioChannels, params->fSendAudioChannels)); fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate); fCycleBytesSize = params->fMtu * (fPeriodSize / fSubPeriodSize); fLastSubCycle = -1; } NetFloatAudioBuffer::~NetFloatAudioBuffer() {} // needed size in bytes for an entire cycle size_t NetFloatAudioBuffer::GetCycleSize() { return fCycleBytesSize; } // cycle duration in sec float NetFloatAudioBuffer::GetCycleDuration() { return fCycleDuration; } void NetFloatAudioBuffer::UpdateParams(int active_ports) { if (active_ports == 0) { fSubPeriodSize = fPeriodSize; } else { jack_nframes_t period = int(powf(2.f, int(log(float(fPacketSize) / (active_ports * sizeof(sample_t))) / log(2.)))); fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period; } fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t) + sizeof(int); // The port number in coded on 4 bytes fNumPackets = fPeriodSize / fSubPeriodSize; // At least one packet } int NetFloatAudioBuffer::GetNumPackets(int active_ports) { UpdateParams(active_ports); /* jack_log("GetNumPackets packet = %d fPeriodSize = %d fSubPeriodSize = %d fSubPeriodBytesSize = %d", fPeriodSize / fSubPeriodSize, fPeriodSize, fSubPeriodSize, fSubPeriodBytesSize); */ return fNumPackets; } //jack<->buffer int NetFloatAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num) { // Cleanup all JACK ports at the beginning of the cycle if (sub_cycle == 0) { Cleanup(); } if (port_num > 0) { UpdateParams(port_num); for (uint32_t port_index = 0; port_index < port_num; port_index++) { // Only copy to active ports : read the active port number then audio data int* active_port_address = (int*)(fNetBuffer + port_index * fSubPeriodBytesSize); int active_port = ntohl(*active_port_address); RenderFromNetwork((char*)(active_port_address + 1), active_port, sub_cycle); } } return CheckPacket(cycle, sub_cycle); } int NetFloatAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num) { int active_ports = 0; for (int port_index = 0; port_index < fNPorts; port_index++) { // Only copy from active ports : write the active port number then audio data if (fPortBuffer[port_index]) { int* active_port_address = (int*)(fNetBuffer + active_ports * fSubPeriodBytesSize); *active_port_address = htonl(port_index); RenderToNetwork((char*)(active_port_address + 1), port_index, sub_cycle); active_ports++; } } return port_num * fSubPeriodBytesSize; } #ifdef __BIG_ENDIAN__ static inline jack_default_audio_sample_t SwapFloat(jack_default_audio_sample_t f) { union { jack_default_audio_sample_t f; unsigned char b[4]; } dat1, dat2; dat1.f = f; dat2.b[0] = dat1.b[3]; dat2.b[1] = dat1.b[2]; dat2.b[2] = dat1.b[1]; dat2.b[3] = dat1.b[0]; return dat2.f; } void NetFloatAudioBuffer::RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle) { if (fPortBuffer[active_port]) { jack_default_audio_sample_t* src = (jack_default_audio_sample_t*)(net_buffer); jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*)(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize); for (unsigned int sample = 0; sample < (fSubPeriodBytesSize - sizeof(int)) / sizeof(jack_default_audio_sample_t); sample++) { dst[sample] = SwapFloat(src[sample]); } } } void NetFloatAudioBuffer::RenderToNetwork(char* net_buffer, int active_port, int sub_cycle) { for (int port_index = 0; port_index < fNPorts; port_index++ ) { jack_default_audio_sample_t* src = (jack_default_audio_sample_t*)(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize); jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*)(net_buffer); for (unsigned int sample = 0; sample < (fSubPeriodBytesSize - sizeof(int)) / sizeof(jack_default_audio_sample_t); sample++) { dst[sample] = SwapFloat(src[sample]); } } } #else void NetFloatAudioBuffer::RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle) { if (fPortBuffer[active_port]) { memcpy(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, net_buffer, fSubPeriodBytesSize - sizeof(int)); } } void NetFloatAudioBuffer::RenderToNetwork(char* net_buffer, int active_port, int sub_cycle) { memcpy(net_buffer, fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(int)); } #endif // Celt audio buffer ********************************************************************************* #if HAVE_CELT #define KPS 32 #define KPS_DIV 8 NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps) :NetAudioBuffer(params, nports, net_buffer) { fCeltMode = new CELTMode*[fNPorts]; fCeltEncoder = new CELTEncoder*[fNPorts]; fCeltDecoder = new CELTDecoder*[fNPorts]; memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*)); memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*)); memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*)); int error = CELT_OK; for (int i = 0; i < fNPorts; i++) { fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error); if (error != CELT_OK) { jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error); goto error; } #if HAVE_CELT_API_0_11 fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error); if (error != CELT_OK) { jack_log("NetCeltAudioBuffer celt_encoder_create_custom err = %d", error); goto error; } celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1)); fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error); if (error != CELT_OK) { jack_log("NetCeltAudioBuffer celt_decoder_create_custom err = %d", error); goto error; } celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1)); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error); if (error != CELT_OK) { jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error); goto error; } celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1)); fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error); if (error != CELT_OK) { jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error); goto error; } celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1)); #else fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]); if (error != CELT_OK) { jack_log("NetCeltAudioBuffer celt_encoder_create err = %d", error); goto error; } celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1)); fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]); if (error != CELT_OK) { jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error); goto error; } celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1)); #endif } { fPeriodSize = params->fPeriodSize; fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8); jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte); fCompressedBuffer = new unsigned char* [fNPorts]; for (int port_index = 0; port_index < fNPorts; port_index++) { fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte]; memset(fCompressedBuffer[port_index], 0, fCompressedSizeByte * sizeof(char)); } int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params); int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params); fNumPackets = (res1) ? (res2 + 1) : res2; jack_log("NetCeltAudioBuffer res1 = %d res2 = %d", res1, res2); fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; jack_log("NetCeltAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); fCycleBytesSize = params->fMtu * fNumPackets; fLastSubCycle = -1; return; } error: FreeCelt(); throw std::bad_alloc(); } NetCeltAudioBuffer::~NetCeltAudioBuffer() { FreeCelt(); for (int port_index = 0; port_index < fNPorts; port_index++) { delete [] fCompressedBuffer[port_index]; } delete [] fCompressedBuffer; } void NetCeltAudioBuffer::FreeCelt() { for (int i = 0; i < fNPorts; i++) { if (fCeltEncoder[i]) { celt_encoder_destroy(fCeltEncoder[i]); } if (fCeltDecoder[i]) { celt_decoder_destroy(fCeltDecoder[i]); } if (fCeltMode[i]) { celt_mode_destroy(fCeltMode[i]); } } delete [] fCeltMode; delete [] fCeltEncoder; delete [] fCeltDecoder; } size_t NetCeltAudioBuffer::GetCycleSize() { return fCycleBytesSize; } float NetCeltAudioBuffer::GetCycleDuration() { return fCycleDuration; } int NetCeltAudioBuffer::GetNumPackets(int active_ports) { return fNumPackets; } int NetCeltAudioBuffer::RenderFromJackPorts(int nframes) { float buffer[BUFFER_SIZE_MAX]; for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t)); } else { memset(buffer, 0, fPeriodSize * sizeof(sample_t)); } #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 //int res = celt_encode_float(fCeltEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte); int res = celt_encode_float(fCeltEncoder[port_index], buffer, nframes, fCompressedBuffer[port_index], fCompressedSizeByte); #else int res = celt_encode_float(fCeltEncoder[port_index], buffer, NULL, fCompressedBuffer[port_index], fCompressedSizeByte); #endif if (res != fCompressedSizeByte) { jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res); } } // All ports active return fNPorts; } void NetCeltAudioBuffer::RenderToJackPorts(int nframes) { for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 //int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], fPeriodSize); int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], nframes); #else int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]); #endif if (res != CELT_OK) { jack_error("celt_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res); } } } NextCycle(); } //network<->buffer int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num) { // Cleanup all JACK ports at the beginning of the cycle if (sub_cycle == 0) { Cleanup(); } if (port_num > 0) { int sub_period_bytes_size; // Last packet of the cycle if (sub_cycle == fNumPackets - 1) { sub_period_bytes_size = fLastSubPeriodBytesSize; } else { sub_period_bytes_size = fSubPeriodBytesSize; } for (int port_index = 0; port_index < fNPorts; port_index++) { memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * sub_period_bytes_size, sub_period_bytes_size); } } return CheckPacket(cycle, sub_cycle); } int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num) { int sub_period_bytes_size; // Last packet of the cycle if (sub_cycle == fNumPackets - 1) { sub_period_bytes_size = fLastSubPeriodBytesSize; } else { sub_period_bytes_size = fSubPeriodBytesSize; } for (int port_index = 0; port_index < fNPorts; port_index++) { memcpy(fNetBuffer + port_index * sub_period_bytes_size, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, sub_period_bytes_size); } return fNPorts * sub_period_bytes_size; } #endif #if HAVE_OPUS #define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length) NetOpusAudioBuffer::NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps) :NetAudioBuffer(params, nports, net_buffer) { fOpusMode = new OpusCustomMode*[fNPorts]; fOpusEncoder = new OpusCustomEncoder*[fNPorts]; fOpusDecoder = new OpusCustomDecoder*[fNPorts]; fCompressedSizesByte = new unsigned short[fNPorts]; memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*)); memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*)); memset(fOpusDecoder, 0, fNPorts * sizeof(OpusCustomDecoder*)); memset(fCompressedSizesByte, 0, fNPorts * sizeof(short)); int error = OPUS_OK; for (int i = 0; i < fNPorts; i++) { /* Allocate en/decoders */ fOpusMode[i] = opus_custom_mode_create(params->fSampleRate, params->fPeriodSize, &error); if (error != OPUS_OK) { jack_log("NetOpusAudioBuffer opus_custom_mode_create err = %d", error); goto error; } fOpusEncoder[i] = opus_custom_encoder_create(fOpusMode[i], 1, &error); if (error != OPUS_OK) { jack_log("NetOpusAudioBuffer opus_custom_encoder_create err = %d", error); goto error; } fOpusDecoder[i] = opus_custom_decoder_create(fOpusMode[i], 1, &error); if (error != OPUS_OK) { jack_log("NetOpusAudioBuffer opus_custom_decoder_create err = %d", error); goto error; } opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_BITRATE(kbps*1024)); // bits per second opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_COMPLEXITY(10)); opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY)); } { fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8); fPeriodSize = params->fPeriodSize; jack_log("NetOpusAudioBuffer fCompressedMaxSizeByte %d", fCompressedMaxSizeByte); fCompressedBuffer = new unsigned char* [fNPorts]; for (int port_index = 0; port_index < fNPorts; port_index++) { fCompressedBuffer[port_index] = new unsigned char[fCompressedMaxSizeByte]; memset(fCompressedBuffer[port_index], 0, fCompressedMaxSizeByte * sizeof(char)); } int res1 = (fNPorts * (fCompressedMaxSizeByte + CDO)) % PACKET_AVAILABLE_SIZE(params); int res2 = (fNPorts * (fCompressedMaxSizeByte + CDO)) / PACKET_AVAILABLE_SIZE(params); fNumPackets = (res1) ? (res2 + 1) : res2; jack_log("NetOpusAudioBuffer res1 = %d res2 = %d", res1, res2); fSubPeriodBytesSize = (fCompressedMaxSizeByte + CDO) / fNumPackets; fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedMaxSizeByte + CDO) % fNumPackets; if (fNumPackets == 1) { fSubPeriodBytesSize = fLastSubPeriodBytesSize; } jack_log("NetOpusAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); fCycleBytesSize = params->fMtu * fNumPackets; fLastSubCycle = -1; return; } error: FreeOpus(); throw std::bad_alloc(); } NetOpusAudioBuffer::~NetOpusAudioBuffer() { FreeOpus(); for (int port_index = 0; port_index < fNPorts; port_index++) { delete [] fCompressedBuffer[port_index]; } delete [] fCompressedBuffer; delete [] fCompressedSizesByte; } void NetOpusAudioBuffer::FreeOpus() { for (int i = 0; i < fNPorts; i++) { if (fOpusEncoder[i]) { opus_custom_encoder_destroy(fOpusEncoder[i]); fOpusEncoder[i] = 0; } if (fOpusDecoder[i]) { opus_custom_decoder_destroy(fOpusDecoder[i]); fOpusDecoder[i] = 0; } if (fOpusMode[i]) { opus_custom_mode_destroy(fOpusMode[i]); fOpusMode[i] = 0; } } delete [] fOpusEncoder; delete [] fOpusDecoder; delete [] fOpusMode; } size_t NetOpusAudioBuffer::GetCycleSize() { return fCycleBytesSize; } float NetOpusAudioBuffer::GetCycleDuration() { return fCycleDuration; } int NetOpusAudioBuffer::GetNumPackets(int active_ports) { return fNumPackets; } int NetOpusAudioBuffer::RenderFromJackPorts(int nframes) { float buffer[BUFFER_SIZE_MAX]; for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t)); } else { memset(buffer, 0, fPeriodSize * sizeof(sample_t)); } int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, ((nframes == -1) ? fPeriodSize : nframes), fCompressedBuffer[port_index], fCompressedMaxSizeByte); if (res < 0 || res >= 65535) { jack_error("opus_custom_encode_float error res = %d", res); fCompressedSizesByte[port_index] = 0; } else { fCompressedSizesByte[port_index] = res; } } // All ports active return fNPorts; } void NetOpusAudioBuffer::RenderToJackPorts(int nframes) { for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { int res = opus_custom_decode_float(fOpusDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizesByte[port_index], fPortBuffer[port_index], ((nframes == -1) ? fPeriodSize : nframes)); if (res < 0 || res != ((nframes == -1) ? fPeriodSize : nframes)) { jack_error("opus_custom_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res); } } } NextCycle(); } //network<->buffer int NetOpusAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num) { // Cleanup all JACK ports at the beginning of the cycle if (sub_cycle == 0) { Cleanup(); } if (port_num > 0) { if (sub_cycle == 0) { for (int port_index = 0; port_index < fNPorts; port_index++) { size_t len = *((size_t*)(fNetBuffer + port_index * fSubPeriodBytesSize)); fCompressedSizesByte[port_index] = ntohs(len); memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + CDO + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize - CDO); } } else if (sub_cycle == fNumPackets - 1) { for (int port_index = 0; port_index < fNPorts; port_index++) { memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); } } else { for (int port_index = 0; port_index < fNPorts; port_index++) { memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); } } } return CheckPacket(cycle, sub_cycle); } int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num) { if (sub_cycle == 0) { for (int port_index = 0; port_index < fNPorts; port_index++) { unsigned short len = htons(fCompressedSizesByte[port_index]); memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, &len, CDO); memcpy(fNetBuffer + port_index * fSubPeriodBytesSize + CDO, fCompressedBuffer[port_index], fSubPeriodBytesSize - CDO); } return fNPorts * fSubPeriodBytesSize; } else if (sub_cycle == fNumPackets - 1) { for (int port_index = 0; port_index < fNPorts; port_index++) { memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fLastSubPeriodBytesSize); } return fNPorts * fLastSubPeriodBytesSize; } else { for (int port_index = 0; port_index < fNPorts; port_index++) { memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fSubPeriodBytesSize); } return fNPorts * fSubPeriodBytesSize; } } #endif NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer) : NetAudioBuffer(params, nports, net_buffer) { fPeriodSize = params->fPeriodSize; fCompressedSizeByte = (params->fPeriodSize * sizeof(short)); jack_log("NetIntAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte); fIntBuffer = new short* [fNPorts]; for (int port_index = 0; port_index < fNPorts; port_index++) { fIntBuffer[port_index] = new short[fPeriodSize]; memset(fIntBuffer[port_index], 0, fPeriodSize * sizeof(short)); } int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params); int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params); jack_log("NetIntAudioBuffer res1 = %d res2 = %d", res1, res2); fNumPackets = (res1) ? (res2 + 1) : res2; fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; fSubPeriodSize = fSubPeriodBytesSize / sizeof(short); jack_log("NetIntAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); fCycleBytesSize = params->fMtu * fNumPackets; fLastSubCycle = -1; } NetIntAudioBuffer::~NetIntAudioBuffer() { for (int port_index = 0; port_index < fNPorts; port_index++) { delete [] fIntBuffer[port_index]; } delete [] fIntBuffer; } size_t NetIntAudioBuffer::GetCycleSize() { return fCycleBytesSize; } float NetIntAudioBuffer::GetCycleDuration() { return fCycleDuration; } int NetIntAudioBuffer::GetNumPackets(int active_ports) { return fNumPackets; } int NetIntAudioBuffer::RenderFromJackPorts(int nframes) { for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { for (int frame = 0; frame < nframes; frame++) { fIntBuffer[port_index][frame] = short(fPortBuffer[port_index][frame] * 32767.f); } } else { memset(fIntBuffer[port_index], 0, fPeriodSize * sizeof(short)); } } // All ports active return fNPorts; } void NetIntAudioBuffer::RenderToJackPorts(int nframes) { float coef = 1.f / 32767.f; for (int port_index = 0; port_index < fNPorts; port_index++) { if (fPortBuffer[port_index]) { for (int frame = 0; frame < nframes; frame++) { fPortBuffer[port_index][frame] = float(fIntBuffer[port_index][frame] * coef); } } } NextCycle(); } //network<->buffer int NetIntAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num) { // Cleanup all JACK ports at the beginning of the cycle if (sub_cycle == 0) { Cleanup(); } if (port_num > 0) { int sub_period_bytes_size; // Last packet if (sub_cycle == fNumPackets - 1) { sub_period_bytes_size = fLastSubPeriodBytesSize; } else { sub_period_bytes_size = fSubPeriodBytesSize; } for (int port_index = 0; port_index < fNPorts; port_index++) { memcpy(fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fNetBuffer + port_index * sub_period_bytes_size, sub_period_bytes_size); } } return CheckPacket(cycle, sub_cycle); } int NetIntAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num) { int sub_period_bytes_size; // Last packet if (sub_cycle == fNumPackets - 1) { sub_period_bytes_size = fLastSubPeriodBytesSize; } else { sub_period_bytes_size = fSubPeriodBytesSize; } for (int port_index = 0; port_index < fNPorts; port_index++) { memcpy(fNetBuffer + port_index * sub_period_bytes_size, fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, sub_period_bytes_size); } return fNPorts * sub_period_bytes_size; } // SessionParams ************************************************************************************ SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params) { memcpy(dst_params, src_params, sizeof(session_params_t)); dst_params->fProtocolVersion = htonl(src_params->fProtocolVersion); dst_params->fPacketID = htonl(src_params->fPacketID); dst_params->fMtu = htonl(src_params->fMtu); dst_params->fID = htonl(src_params->fID); dst_params->fTransportSync = htonl(src_params->fTransportSync); dst_params->fSendAudioChannels = htonl(src_params->fSendAudioChannels); dst_params->fReturnAudioChannels = htonl(src_params->fReturnAudioChannels); dst_params->fSendMidiChannels = htonl(src_params->fSendMidiChannels); dst_params->fReturnMidiChannels = htonl(src_params->fReturnMidiChannels); dst_params->fSampleRate = htonl(src_params->fSampleRate); dst_params->fPeriodSize = htonl(src_params->fPeriodSize); dst_params->fSampleEncoder = htonl(src_params->fSampleEncoder); dst_params->fKBps = htonl(src_params->fKBps); dst_params->fSlaveSyncMode = htonl(src_params->fSlaveSyncMode); dst_params->fNetworkLatency = htonl(src_params->fNetworkLatency); } SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params) { memcpy(dst_params, src_params, sizeof(session_params_t)); dst_params->fProtocolVersion = ntohl(src_params->fProtocolVersion); dst_params->fPacketID = ntohl(src_params->fPacketID); dst_params->fMtu = ntohl(src_params->fMtu); dst_params->fID = ntohl(src_params->fID); dst_params->fTransportSync = ntohl(src_params->fTransportSync); dst_params->fSendAudioChannels = ntohl(src_params->fSendAudioChannels); dst_params->fReturnAudioChannels = ntohl(src_params->fReturnAudioChannels); dst_params->fSendMidiChannels = ntohl(src_params->fSendMidiChannels); dst_params->fReturnMidiChannels = ntohl(src_params->fReturnMidiChannels); dst_params->fSampleRate = ntohl(src_params->fSampleRate); dst_params->fPeriodSize = ntohl(src_params->fPeriodSize); dst_params->fSampleEncoder = ntohl(src_params->fSampleEncoder); dst_params->fKBps = ntohl(src_params->fKBps); dst_params->fSlaveSyncMode = ntohl(src_params->fSlaveSyncMode); dst_params->fNetworkLatency = ntohl(src_params->fNetworkLatency); } SERVER_EXPORT void SessionParamsDisplay(session_params_t* params) { char encoder[16]; switch (params->fSampleEncoder) { case JackFloatEncoder: strcpy(encoder, "float"); break; case JackIntEncoder: strcpy(encoder, "integer"); break; case JackCeltEncoder: strcpy(encoder, "CELT"); break; case JackOpusEncoder: strcpy(encoder, "OPUS"); break; } jack_info("**************** Network parameters ****************"); jack_info("Name : %s", params->fName); jack_info("Protocol revision : %d", params->fProtocolVersion); jack_info("MTU : %u", params->fMtu); jack_info("Master name : %s", params->fMasterNetName); jack_info("Slave name : %s", params->fSlaveNetName); jack_info("ID : %u", params->fID); jack_info("Transport Sync : %s", (params->fTransportSync) ? "yes" : "no"); jack_info("Send channels (audio - midi) : %d - %d", params->fSendAudioChannels, params->fSendMidiChannels); jack_info("Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels); jack_info("Sample rate : %u frames per second", params->fSampleRate); jack_info("Period size : %u frames per period", params->fPeriodSize); jack_info("Network latency : %u cycles", params->fNetworkLatency); switch (params->fSampleEncoder) { case (JackFloatEncoder): jack_info("SampleEncoder : %s", "Float"); break; case (JackIntEncoder): jack_info("SampleEncoder : %s", "16 bits integer"); break; case (JackCeltEncoder): jack_info("SampleEncoder : %s", "CELT"); jack_info("kBits : %d", params->fKBps); break; case (JackOpusEncoder): jack_info("SampleEncoder : %s", "OPUS"); jack_info("kBits : %d", params->fKBps); break; }; jack_info("Slave mode : %s", (params->fSlaveSyncMode) ? "sync" : "async"); jack_info("****************************************************"); } SERVER_EXPORT sync_packet_type_t GetPacketType(session_params_t* params) { switch (params->fPacketID) { case 0: return SLAVE_AVAILABLE; case 1: return SLAVE_SETUP; case 2: return START_MASTER; case 3: return START_SLAVE; case 4: return KILL_MASTER; } return INVALID; } SERVER_EXPORT int SetPacketType(session_params_t* params, sync_packet_type_t packet_type) { switch (packet_type) { case INVALID: return -1; case SLAVE_AVAILABLE: params->fPacketID = 0; break; case SLAVE_SETUP: params->fPacketID = 1; break; case START_MASTER: params->fPacketID = 2; break; case START_SLAVE: params->fPacketID = 3; break; case KILL_MASTER: params->fPacketID = 4; } return 0; } // Packet header ********************************************************************************** SERVER_EXPORT void PacketHeaderHToN(packet_header_t* src_header, packet_header_t* dst_header) { memcpy(dst_header, src_header, sizeof(packet_header_t)); dst_header->fDataType = htonl(src_header->fDataType); dst_header->fDataStream = htonl(src_header->fDataStream); dst_header->fID = htonl(src_header->fID); dst_header->fNumPacket = htonl(src_header->fNumPacket); dst_header->fPacketSize = htonl(src_header->fPacketSize); dst_header->fActivePorts = htonl(src_header->fActivePorts); dst_header->fCycle = htonl(src_header->fCycle); dst_header->fSubCycle = htonl(src_header->fSubCycle); dst_header->fFrames = htonl(src_header->fFrames); dst_header->fIsLastPckt = htonl(src_header->fIsLastPckt); } SERVER_EXPORT void PacketHeaderNToH(packet_header_t* src_header, packet_header_t* dst_header) { memcpy(dst_header, src_header, sizeof(packet_header_t)); dst_header->fDataType = ntohl(src_header->fDataType); dst_header->fDataStream = ntohl(src_header->fDataStream); dst_header->fID = ntohl(src_header->fID); dst_header->fNumPacket = ntohl(src_header->fNumPacket); dst_header->fPacketSize = ntohl(src_header->fPacketSize); dst_header->fActivePorts = ntohl(src_header->fActivePorts); dst_header->fCycle = ntohl(src_header->fCycle); dst_header->fSubCycle = ntohl(src_header->fSubCycle); dst_header->fFrames = ntohl(src_header->fFrames); dst_header->fIsLastPckt = ntohl(src_header->fIsLastPckt); } SERVER_EXPORT void PacketHeaderDisplay(packet_header_t* header) { jack_info("********************Header********************"); jack_info("Data type : %c", header->fDataType); jack_info("Data stream : %c", header->fDataStream); jack_info("ID : %u", header->fID); jack_info("Cycle : %u", header->fCycle); jack_info("SubCycle : %u", header->fSubCycle); jack_info("Active ports : %u", header->fActivePorts); jack_info("DATA packets : %u", header->fNumPacket); jack_info("DATA size : %u", header->fPacketSize); jack_info("DATA frames : %d", header->fFrames); jack_info("Last packet : '%s'", (header->fIsLastPckt) ? "yes" : "no"); jack_info("**********************************************"); } SERVER_EXPORT void NetTransportDataDisplay(net_transport_data_t* data) { jack_info("********************Network Transport********************"); jack_info("Transport new state : %u", data->fNewState); jack_info("Transport timebase master : %u", data->fTimebaseMaster); jack_info("Transport cycle state : %u", data->fState); jack_info("**********************************************"); } SERVER_EXPORT void MidiBufferHToN(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer) { dst_buffer->magic = htonl(src_buffer->magic); dst_buffer->buffer_size = htonl(src_buffer->buffer_size); dst_buffer->nframes = htonl(src_buffer->nframes); dst_buffer->write_pos = htonl(src_buffer->write_pos); dst_buffer->event_count = htonl(src_buffer->event_count); dst_buffer->lost_events = htonl(src_buffer->lost_events); } SERVER_EXPORT void MidiBufferNToH(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer) { dst_buffer->magic = ntohl(src_buffer->magic); dst_buffer->buffer_size = ntohl(src_buffer->buffer_size); dst_buffer->nframes = ntohl(src_buffer->nframes); dst_buffer->write_pos = ntohl(src_buffer->write_pos); dst_buffer->event_count = ntohl(src_buffer->event_count); dst_buffer->lost_events = ntohl(src_buffer->lost_events); } SERVER_EXPORT void TransportDataHToN(net_transport_data_t* src_params, net_transport_data_t* dst_params) { dst_params->fNewState = htonl(src_params->fNewState); dst_params->fTimebaseMaster = htonl(src_params->fTimebaseMaster); dst_params->fState = htonl(src_params->fState); dst_params->fPosition.unique_1 = htonll(src_params->fPosition.unique_1); dst_params->fPosition.usecs = htonl(src_params->fPosition.usecs); dst_params->fPosition.frame_rate = htonl(src_params->fPosition.frame_rate); dst_params->fPosition.frame = htonl(src_params->fPosition.frame); dst_params->fPosition.valid = (jack_position_bits_t)htonl((uint32_t)src_params->fPosition.valid); dst_params->fPosition.bar = htonl(src_params->fPosition.bar); dst_params->fPosition.beat = htonl(src_params->fPosition.beat); dst_params->fPosition.tick = htonl(src_params->fPosition.tick); dst_params->fPosition.bar_start_tick = htonll((uint64_t)src_params->fPosition.bar_start_tick); dst_params->fPosition.beats_per_bar = htonl((uint32_t)src_params->fPosition.beats_per_bar); dst_params->fPosition.beat_type = htonl((uint32_t)src_params->fPosition.beat_type); dst_params->fPosition.ticks_per_beat = htonll((uint64_t)src_params->fPosition.ticks_per_beat); dst_params->fPosition.beats_per_minute = htonll((uint64_t)src_params->fPosition.beats_per_minute); dst_params->fPosition.frame_time = htonll((uint64_t)src_params->fPosition.frame_time); dst_params->fPosition.next_time = htonll((uint64_t)src_params->fPosition.next_time); dst_params->fPosition.bbt_offset = htonl(src_params->fPosition.bbt_offset); dst_params->fPosition.audio_frames_per_video_frame = htonl((uint32_t)src_params->fPosition.audio_frames_per_video_frame); dst_params->fPosition.video_offset = htonl(src_params->fPosition.video_offset); dst_params->fPosition.unique_2 = htonll(src_params->fPosition.unique_2); } SERVER_EXPORT void TransportDataNToH(net_transport_data_t* src_params, net_transport_data_t* dst_params) { dst_params->fNewState = ntohl(src_params->fNewState); dst_params->fTimebaseMaster = ntohl(src_params->fTimebaseMaster); dst_params->fState = ntohl(src_params->fState); dst_params->fPosition.unique_1 = ntohll(src_params->fPosition.unique_1); dst_params->fPosition.usecs = ntohl(src_params->fPosition.usecs); dst_params->fPosition.frame_rate = ntohl(src_params->fPosition.frame_rate); dst_params->fPosition.frame = ntohl(src_params->fPosition.frame); dst_params->fPosition.valid = (jack_position_bits_t)ntohl((uint32_t)src_params->fPosition.valid); dst_params->fPosition.bar = ntohl(src_params->fPosition.bar); dst_params->fPosition.beat = ntohl(src_params->fPosition.beat); dst_params->fPosition.tick = ntohl(src_params->fPosition.tick); dst_params->fPosition.bar_start_tick = ntohll((uint64_t)src_params->fPosition.bar_start_tick); dst_params->fPosition.beats_per_bar = ntohl((uint32_t)src_params->fPosition.beats_per_bar); dst_params->fPosition.beat_type = ntohl((uint32_t)src_params->fPosition.beat_type); dst_params->fPosition.ticks_per_beat = ntohll((uint64_t)src_params->fPosition.ticks_per_beat); dst_params->fPosition.beats_per_minute = ntohll((uint64_t)src_params->fPosition.beats_per_minute); dst_params->fPosition.frame_time = ntohll((uint64_t)src_params->fPosition.frame_time); dst_params->fPosition.next_time = ntohll((uint64_t)src_params->fPosition.next_time); dst_params->fPosition.bbt_offset = ntohl(src_params->fPosition.bbt_offset); dst_params->fPosition.audio_frames_per_video_frame = ntohl((uint32_t)src_params->fPosition.audio_frames_per_video_frame); dst_params->fPosition.video_offset = ntohl(src_params->fPosition.video_offset); dst_params->fPosition.unique_2 = ntohll(src_params->fPosition.unique_2); } // Utility ******************************************************************************************************* SERVER_EXPORT int SocketAPIInit() { #ifdef WIN32 WORD wVersionRequested = MAKEWORD(2, 2); WSADATA wsaData; if (WSAStartup(wVersionRequested, &wsaData) != 0) { jack_error("WSAStartup error : %s", strerror(NET_ERROR_CODE)); return -1; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { jack_error("Could not find a useable version of Winsock.dll\n"); WSACleanup(); return -1; } #endif return 0; } SERVER_EXPORT int SocketAPIEnd() { #ifdef WIN32 return WSACleanup(); #endif return 0; } SERVER_EXPORT const char* GetTransportState(int transport_state) { switch (transport_state) { case JackTransportRolling: return "rolling"; case JackTransportStarting: return "starting"; case JackTransportStopped: return "stopped"; case JackTransportNetStarting: return "netstarting"; } return NULL; } } 1.9.12~dfsg/common/JackMidiSendQueue.h0000644000000000000000000000246713214314510016304 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiSendQueue__ #define __JackMidiSendQueue__ #include "JackMidiWriteQueue.h" namespace Jack { /** * Implemented by MIDI output connections. */ class SERVER_EXPORT JackMidiSendQueue: public JackMidiWriteQueue { public: using JackMidiWriteQueue::EnqueueEvent; virtual ~JackMidiSendQueue(); /** * Returns the next frame that a MIDI message can be sent at. The * default method returns the current frame. */ virtual jack_nframes_t GetNextScheduleFrame(); }; } #endif 1.9.12~dfsg/common/JackInternalClient.cpp0000644000000000000000000001614113214314510017043 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackServerGlobals.h" #include "JackGraphManager.h" #include "JackConstants.h" #include "JackInternalClient.h" #include "JackLockedEngine.h" #include "JackServer.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackInternalClientChannel.h" #include "JackTools.h" #include namespace Jack { JackGraphManager* JackInternalClient::fGraphManager = NULL; JackEngineControl* JackInternalClient::fEngineControl = NULL; // Used for external C API (JackAPI.cpp) SERVER_EXPORT JackGraphManager* GetGraphManager() { return JackServerGlobals::fInstance->GetGraphManager(); } SERVER_EXPORT JackEngineControl* GetEngineControl() { return JackServerGlobals::fInstance->GetEngineControl(); } SERVER_EXPORT JackSynchro* GetSynchroTable() { return JackServerGlobals::fInstance->GetSynchroTable(); } JackInternalClient::JackInternalClient(JackServer* server, JackSynchro* table): JackClient(table) { fChannel = new JackInternalClientChannel(server); } JackInternalClient::~JackInternalClient() { delete fChannel; } int JackInternalClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int result; jack_log("JackInternalClient::Open name = %s", name); if (strlen(name) >= JACK_CLIENT_NAME_SIZE) { jack_error("\"%s\" is too long to be used as a JACK client name.\n" "Please use %lu characters or less", name, JACK_CLIENT_NAME_SIZE - 1); return -1; } strncpy(fServerName, server_name, sizeof(fServerName)); // Open server/client direct channel char name_res[JACK_CLIENT_NAME_SIZE + 1]; fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, false); if (result < 0) { int status1 = *status; if (status1 & JackVersionError) { jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); } else { jack_error("Client name = %s conflits with another running client", name); } goto error; } strcpy(fClientControl.fName, name_res); // Require new client fChannel->ClientOpen(name_res, &fClientControl.fRefNum, &fEngineControl, &fGraphManager, this, &result); if (result < 0) { jack_error("Cannot open client name = %s", name_res); goto error; } SetupDriverSync(false); JackGlobals::fClientTable[fClientControl.fRefNum] = this; JackGlobals::fServerRunning = true; jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum); return 0; error: fChannel->Close(); return -1; } void JackInternalClient::ShutDown(jack_status_t code, const char* message) { jack_log("JackInternalClient::ShutDown"); JackClient::ShutDown(code, message); } JackGraphManager* JackInternalClient::GetGraphManager() const { assert(fGraphManager); return fGraphManager; } JackEngineControl* JackInternalClient::GetEngineControl() const { assert(fEngineControl); return fEngineControl; } JackClientControl* JackInternalClient::GetClientControl() const { return const_cast(&fClientControl); } int JackLoadableInternalClient::Init(const char* so_name) { char path_to_so[JACK_PATH_MAX + 1]; BuildClientPath(path_to_so, sizeof(path_to_so), so_name); fHandle = LoadJackModule(path_to_so); jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so); if (fHandle == NULL) { PrintLoadError(so_name); return -1; } fFinish = (FinishCallback)GetJackProc(fHandle, "jack_finish"); if (fFinish == NULL) { UnloadJackModule(fHandle); jack_error("symbol jack_finish cannot be found in %s", so_name); return -1; } fDescriptor = (JackDriverDescFunction)GetJackProc(fHandle, "jack_get_descriptor"); if (fDescriptor == NULL) { jack_info("No jack_get_descriptor entry-point for %s", so_name); } return 0; } int JackLoadableInternalClient1::Init(const char* so_name) { if (JackLoadableInternalClient::Init(so_name) < 0) { return -1; } fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize"); if (fInitialize == NULL) { UnloadJackModule(fHandle); jack_error("symbol jack_initialize cannot be found in %s", so_name); return -1; } return 0; } int JackLoadableInternalClient2::Init(const char* so_name) { if (JackLoadableInternalClient::Init(so_name) < 0) { return -1; } fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize"); if (fInitialize == NULL) { UnloadJackModule(fHandle); jack_error("symbol jack_internal_initialize cannot be found in %s", so_name); return -1; } return 0; } JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data) : JackLoadableInternalClient(server, table) { strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT); } JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters) : JackLoadableInternalClient(server, table) { fParameters = parameters; } JackLoadableInternalClient::~JackLoadableInternalClient() { if (fFinish != NULL) { fFinish(fProcessArg); } if (fHandle != NULL) { UnloadJackModule(fHandle); } } int JackLoadableInternalClient1::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int res = -1; if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { if (fInitialize((jack_client_t*)this, fObjectData) == 0) { res = 0; } else { JackInternalClient::Close(); fFinish = NULL; } } return res; } int JackLoadableInternalClient2::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int res = -1; if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { if (fInitialize((jack_client_t*)this, fParameters) == 0) { res = 0; } else { JackInternalClient::Close(); fFinish = NULL; } } return res; } } // end of namespace 1.9.12~dfsg/common/JackDriver.cpp0000644000000000000000000004262113214314510015365 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackDriver.h" #include "JackTime.h" #include "JackError.h" #include "JackPort.h" #include "JackGraphManager.h" #include "JackGlobals.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackLockedEngine.h" #include "JackTime.h" #include #include using namespace std; namespace Jack { JackDriver::JackDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) :fCaptureChannels(0), fPlaybackChannels(0), fClientControl(name), fWithMonitorPorts(false){ assert(strlen(name) < JACK_CLIENT_NAME_SIZE); fSynchroTable = table; strcpy(fAliasName, alias); fEngine = engine; fGraphManager = NULL; fBeginDateUst = 0; fEndDateUst = 0; fDelayedUsecs = 0.f; fIsMaster = true; fIsRunning = false; } JackDriver::~JackDriver() { jack_log("~JackDriver"); } int JackDriver::Open() { int refnum = -1; if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { jack_error("Cannot allocate internal client for driver"); return -1; } fClientControl.fRefNum = refnum; fClientControl.fActive = true; fEngineControl->fDriverNum++; fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode SetupDriverSync(fClientControl.fRefNum, false); return 0; } int JackDriver::Open(jack_nframes_t buffer_size, jack_nframes_t sample_rate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name); jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name); int refnum = -1; char name_res[JACK_CLIENT_NAME_SIZE + 1]; int status; // Check name and possibly rename if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (int)JackNullOption, (int*)&status) < 0) { jack_error("Client name = %s conflits with another running client", fClientControl.fName); return -1; } strcpy(fClientControl.fName, name_res); if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { jack_error("Cannot allocate internal client for driver"); return -1; } fClientControl.fRefNum = refnum; fClientControl.fActive = true; fEngineControl->fDriverNum++; if (buffer_size > 0) { fEngineControl->fBufferSize = buffer_size; } if (sample_rate > 0) { fEngineControl->fSampleRate = sample_rate; } fCaptureLatency = capture_latency; fPlaybackLatency = playback_latency; assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE); assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE); strcpy(fCaptureDriverName, capture_driver_name); strcpy(fPlaybackDriverName, playback_driver_name); fEngineControl->UpdateTimeOut(); fGraphManager->SetBufferSize(fEngineControl->fBufferSize); fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode SetupDriverSync(fClientControl.fRefNum, false); return 0; } int JackDriver::Close() { if (fClientControl.fRefNum >= 0) { jack_log("JackDriver::Close"); fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync fClientControl.fActive = false; fEngineControl->fDriverNum--; return fEngine->ClientInternalClose(fClientControl.fRefNum, false); } else { return -1; } } /*! In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel. */ void JackDriver::SetupDriverSync(int ref, bool freewheel) { if (!freewheel && !fEngineControl->fSyncMode) { jack_log("JackDriver::SetupDriverSync driver sem in flush mode"); fSynchroTable[ref].SetFlush(true); } else { jack_log("JackDriver::SetupDriverSync driver sem in normal mode"); fSynchroTable[ref].SetFlush(false); } } int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { jack_log("JackDriver::ClientNotify ref = %ld driver = %s name = %s notify = %ld", refnum, fClientControl.fName, name, notify); switch (notify) { case kStartFreewheelCallback: jack_log("JackDriver::kStartFreewheel"); SetupDriverSync(fClientControl.fRefNum, true); break; case kStopFreewheelCallback: jack_log("JackDriver::kStopFreewheel"); SetupDriverSync(fClientControl.fRefNum, false); break; } return 0; } bool JackDriver::IsRealTime() const { return fEngineControl->fRealTime; } void JackDriver::CycleIncTime() { fEngineControl->CycleIncTime(fBeginDateUst); } void JackDriver::CycleTakeBeginTime() { fBeginDateUst = GetMicroSeconds(); // Take callback date here fEngineControl->CycleIncTime(fBeginDateUst); } void JackDriver::CycleTakeEndTime() { fEndDateUst = GetMicroSeconds(); // Take end date here } JackClientControl* JackDriver::GetClientControl() const { return (JackClientControl*)&fClientControl; } void JackDriver::NotifyXRun(jack_time_t cur_cycle_begin, float delayed_usecs) { fEngineControl->NotifyXRun(cur_cycle_begin, delayed_usecs); fEngine->NotifyDriverXRun(); } void JackDriver::NotifyBufferSize(jack_nframes_t buffer_size) { fEngine->NotifyBufferSize(buffer_size); fEngineControl->InitFrameTime(); } void JackDriver::NotifySampleRate(jack_nframes_t sample_rate) { fEngine->NotifySampleRate(sample_rate); fEngineControl->InitFrameTime(); } void JackDriver::NotifyFailure(int code, const char* reason) { fEngine->NotifyFailure(code, reason); } void JackDriver::SetMaster(bool onoff) { fIsMaster = onoff; } bool JackDriver::GetMaster() { return fIsMaster; } void JackDriver::AddSlave(JackDriverInterface* slave) { fSlaveList.push_back(slave); } void JackDriver::RemoveSlave(JackDriverInterface* slave) { fSlaveList.remove(slave); } int JackDriver::ProcessReadSlaves() { int res = 0; list::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; if (slave->IsRunning()) { if (slave->ProcessRead() < 0) { res = -1; } } } return res; } int JackDriver::ProcessWriteSlaves() { int res = 0; list::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; if (slave->IsRunning()) { if (slave->ProcessWrite() < 0) { res = -1; } } } return res; } int JackDriver::ProcessRead() { return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); } int JackDriver::ProcessWrite() { return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync(); } int JackDriver::ProcessReadSync() { return 0; } int JackDriver::ProcessWriteSync() { return 0; } int JackDriver::ProcessReadAsync() { return 0; } int JackDriver::ProcessWriteAsync() { return 0; } int JackDriver::Process() { return 0; } int JackDriver::Attach() { return 0; } int JackDriver::Detach() { return 0; } int JackDriver::Read() { return 0; } int JackDriver::Write() { return 0; } int JackDriver::Start() { if (fIsMaster) { fEngineControl->InitFrameTime(); } fIsRunning = true; return StartSlaves(); } int JackDriver::Stop() { fIsRunning = false; return StopSlaves(); } int JackDriver::StartSlaves() { int res = 0; list::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; if (slave->Start() < 0) { res = -1; // XXX: We should attempt to stop all of the slaves that we've // started here. break; } } return res; } int JackDriver::StopSlaves() { int res = 0; list::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; if (slave->Stop() < 0) { res = -1; } } return res; } bool JackDriver::IsFixedBufferSize() { return true; } int JackDriver::SetBufferSize(jack_nframes_t buffer_size) { int res = 0; list::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; if (slave->SetBufferSize(buffer_size) < 0) { res = -1; } } return res; } int JackDriver::SetSampleRate(jack_nframes_t sample_rate) { int res = 0; list::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; if (slave->SetSampleRate(sample_rate) < 0) { res = -1; } } return res; } bool JackDriver::Initialize() { return true; } static string RemoveLast(const string& name) { return name.substr(0, name.find_last_of(':')); // Remove end of name after last ":" } void JackDriver::SaveConnections(int alias) { const char** connections; char alias1[REAL_JACK_PORT_NAME_SIZE+1]; char alias2[REAL_JACK_PORT_NAME_SIZE+1]; char system_alias1[REAL_JACK_PORT_NAME_SIZE+1]; char system_alias2[REAL_JACK_PORT_NAME_SIZE+1]; char* aliases[2]; char* system_aliases[2]; aliases[0] = alias1; aliases[1] = alias2; system_aliases[0] = system_alias1; system_aliases[1] = system_alias2; fConnections.clear(); for (int i = 0; i < fCaptureChannels; ++i) { if (fCapturePortList[i] && (connections = fGraphManager->GetConnections(fCapturePortList[i])) != 0) { if (alias == 0) { for (int j = 0; connections[j]; j++) { JackPort* port_id = fGraphManager->GetPort(fCapturePortList[i]); fConnections.push_back(make_pair(port_id->GetType(), make_pair(port_id->GetName(), connections[j]))); jack_info("Save connection: %s %s", fGraphManager->GetPort(fCapturePortList[i])->GetName(), connections[j]); } } else { int res1 = fGraphManager->GetPort(fCapturePortList[i])->GetAliases(aliases); string sub_system_name; if (res1 >= alias) { sub_system_name = aliases[alias-1]; } else { sub_system_name = fGraphManager->GetPort(fCapturePortList[i])->GetName(); } for (int j = 0; connections[j]; j++) { JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j])); int res2 = port_id->GetAliases(system_aliases); string sub_system; if (res2 >= alias) { sub_system = system_aliases[alias-1]; } else { sub_system = connections[j]; } fConnections.push_back(make_pair(port_id->GetType(), make_pair(sub_system_name, sub_system))); jack_info("Save connection: %s %s", sub_system_name.c_str(), sub_system.c_str()); } } free(connections); } } for (int i = 0; i < fPlaybackChannels; ++i) { if (fPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fPlaybackPortList[i])) != 0) { if (alias == 0) { for (int j = 0; connections[j]; j++) { JackPort* port_id = fGraphManager->GetPort(fPlaybackPortList[i]); fConnections.push_back(make_pair(port_id->GetType(), make_pair(connections[j], port_id->GetName()))); jack_info("Save connection: %s %s", connections[j], fGraphManager->GetPort(fPlaybackPortList[i])->GetName()); } } else { int res1 = fGraphManager->GetPort(fPlaybackPortList[i])->GetAliases(aliases); string sub_system_name; if (res1 >= alias) { sub_system_name = aliases[alias-1]; } else { sub_system_name = fGraphManager->GetPort(fPlaybackPortList[i])->GetName(); } for (int j = 0; connections[j]; j++) { JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j])); int res2 = port_id->GetAliases(system_aliases); string sub_name; if (res2 >= alias) { sub_name = system_aliases[alias-1]; } else { sub_name = connections[j]; } fConnections.push_back(make_pair(port_id->GetType(), make_pair(sub_name, sub_system_name))); jack_info("Save connection: %s %s", sub_name.c_str(), sub_system_name.c_str()); } } free(connections); } } } string JackDriver::MatchPortName(const char* name, const char** ports, int alias, const std::string& type) { char alias1[REAL_JACK_PORT_NAME_SIZE+1]; char alias2[REAL_JACK_PORT_NAME_SIZE+1]; char* aliases[2]; aliases[0] = alias1; aliases[1] = alias2; for (int i = 0; ports && ports[i]; ++i) { jack_port_id_t port_id2 = fGraphManager->GetPort(ports[i]); JackPort* port2 = (port_id2 != NO_PORT) ? fGraphManager->GetPort(port_id2) : NULL; if (port2) { int res = port2->GetAliases(aliases); string name_str; if (res >= alias) { name_str = string(aliases[alias-1]); } else { name_str = string(ports[i]); } string sub_name = RemoveLast(name); if ((name_str.find(sub_name) != string::npos) && (type == string(port2->GetType()))) { return name_str; } } } return ""; } void JackDriver::LoadConnections(int alias, bool full_name) { list > >::const_iterator it; if (full_name) { for (it = fConnections.begin(); it != fConnections.end(); it++) { pair connection = (*it).second; jack_info("Load connection: %s %s", connection.first.c_str(), connection.second.c_str()); fEngine->PortConnect(fClientControl.fRefNum, connection.first.c_str(), connection.second.c_str()); } } else { const char** inputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsInput); const char** outputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsOutput); for (it = fConnections.begin(); it != fConnections.end(); it++) { pair connection = (*it).second; string real_input = MatchPortName(connection.first.c_str(), outputs, alias, (*it).first); string real_output = MatchPortName(connection.second.c_str(), inputs, alias, (*it).first); if ((real_input != "") && (real_output != "")) { jack_info("Load connection: %s %s", real_input.c_str(), real_output.c_str()); fEngine->PortConnect(fClientControl.fRefNum, real_input.c_str(), real_output.c_str()); } } // Wait for connection change if (fGraphManager->IsPendingChange()) { JackSleep(int(fEngineControl->fPeriodUsecs * 1.1f)); } if (inputs) { free(inputs); } if (outputs) { free(outputs); } } } int JackDriver::ResumeRefNum() { return fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); } int JackDriver::SuspendRefNum() { return fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs); } } // end of namespace 1.9.12~dfsg/common/JackThreadedDriver.h0000644000000000000000000000633113214314510016471 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackThreadedDriver__ #define __JackThreadedDriver__ #include "JackDriver.h" #include "JackPlatformPlug.h" namespace Jack { /*! \brief The base class for threaded drivers using a "decorator" pattern. Threaded drivers are used with blocking devices. */ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, public JackRunnableInterface { protected: JackThread fThread; JackDriver* fDriver; void SetRealTime(); public: JackThreadedDriver(JackDriver* driver); virtual ~JackThreadedDriver(); virtual int Open(); virtual int Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); virtual int Close(); virtual int Process(); virtual int Attach(); virtual int Detach(); virtual int Read(); virtual int Write(); virtual int Start(); virtual int Stop(); virtual bool IsFixedBufferSize(); virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetSampleRate(jack_nframes_t sample_rate); virtual void SetMaster(bool onoff); virtual bool GetMaster(); virtual void AddSlave(JackDriverInterface* slave); virtual void RemoveSlave(JackDriverInterface* slave); virtual std::list GetSlaves(); virtual int ProcessReadSlaves(); virtual int ProcessWriteSlaves(); virtual int ProcessRead(); virtual int ProcessWrite(); virtual int ProcessReadSync(); virtual int ProcessWriteSync(); virtual int ProcessReadAsync(); virtual int ProcessWriteAsync(); virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; virtual bool IsRunning() const; // JackRunnableInterface interface virtual bool Execute(); virtual bool Init(); }; } // end of namespace #endif 1.9.12~dfsg/common/promiscuous.h0000644000000000000000000000217513214314510015376 0ustar rootroot/* Copyright (C) 2014-2017 Cédric Schieli This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __jack_gid_h__ #define __jack_gid_h__ #ifdef __cplusplus extern "C" { #endif int jack_group2gid (const char *group); /*!< Lookup gid for a UNIX group in a thread-safe way */ #ifndef WIN32 int jack_promiscuous_perms (int fd, const char *path, gid_t gid); /*!< Set promiscuous permissions on object referenced by fd and/or path */ #endif #ifdef __cplusplus } #endif #endif /* __jack_gid_h__ */ 1.9.12~dfsg/common/JackAC3Encoder.h0000644000000000000000000000535313214314510015446 0ustar rootroot/* Copyright (C) 2006 Jesse Chappell (AC3Jack) Copyright (C) 2012 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackAC3Encoder__ #define __JackAC3Encoder__ #include #include #include "ringbuffer.h" #include "types.h" #define MAX_AC3_CHANNELS 6 #define SPDIF_HEADER_SIZE 8 #define SPDIF_FRAME_SIZE 6144 #define SAMPLE_MAX_16BIT 32768.0f #define SAMPLE_MAX_24BIT 8388608.0f namespace Jack { struct JackAC3EncoderParams { int64_t duration; unsigned int channels; int bitdepth; int bitrate; unsigned int sample_rate; bool lfe; }; class JackAC3Encoder { private: AftenContext fAftenContext; jack_ringbuffer_t* fRingBuffer; float* fSampleBuffer; unsigned char* fAC3Buffer; unsigned char* fZeroBuffer; int fOutSizeByte; jack_nframes_t fFramePos; jack_nframes_t fSampleRate; jack_nframes_t fByteRate; void FillSpdifHeader(unsigned char* buf, int outsize); int Output2Driver(float** outputs, jack_nframes_t nframes); void sample_move_dS_s16(jack_default_audio_sample_t* dst, char *src, jack_nframes_t nsamples, unsigned long src_skip); void sample_move_dS_s16_24ph(jack_default_audio_sample_t* dst, char *src, jack_nframes_t nsamples, unsigned long src_skip); public: #ifdef __ppc__ JackAC3Encoder(const JackAC3EncoderParams& params) {} virtual ~JackAC3Encoder() {} bool Init(jack_nframes_t sample_rate) {return false;} void Process(float** inputs, float** outputs, int nframes) {} void GetChannelName(const char* name, const char* alias, char* portname, int channel) {} #else JackAC3Encoder(const JackAC3EncoderParams& params); virtual ~JackAC3Encoder(); bool Init(jack_nframes_t sample_rate); void Process(float** inputs, float** outputs, int nframes); void GetChannelName(const char* name, const char* alias, char* portname, int channel); #endif }; typedef JackAC3Encoder * JackAC3EncoderPtr; } // end of namespace #endif 1.9.12~dfsg/common/JackNetManager.cpp0000644000000000000000000011215013214314510016146 0ustar rootroot/* Copyright(C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackNetManager.h" #include "JackArgParser.h" #include "JackServerGlobals.h" #include "JackLockedEngine.h" #include "thread.h" using namespace std; namespace Jack { //JackNetMaster****************************************************************************************************** JackNetMaster::JackNetMaster(JackNetSocket& socket, session_params_t& params, const char* multicast_ip) : JackNetMasterInterface(params, socket, multicast_ip) { jack_log("JackNetMaster::JackNetMaster"); //settings fName = const_cast(fParams.fName); fClient = NULL; fSendTransportData.fState = -1; fReturnTransportData.fState = -1; fLastTransportState = -1; int port_index; //jack audio ports fAudioCapturePorts = new jack_port_t* [fParams.fSendAudioChannels]; for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { fAudioCapturePorts[port_index] = NULL; } fAudioPlaybackPorts = new jack_port_t* [fParams.fReturnAudioChannels]; for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { fAudioPlaybackPorts[port_index] = NULL; } //jack midi ports fMidiCapturePorts = new jack_port_t* [fParams.fSendMidiChannels]; for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { fMidiCapturePorts[port_index] = NULL; } fMidiPlaybackPorts = new jack_port_t* [fParams.fReturnMidiChannels]; for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { fMidiPlaybackPorts[port_index] = NULL; } //monitor #ifdef JACK_MONITOR fPeriodUsecs = (int)(1000000.f * ((float) fParams.fPeriodSize / (float) fParams.fSampleRate)); string plot_name; plot_name = string(fParams.fName); plot_name += string("_master"); plot_name += string((fParams.fSlaveSyncMode) ? "_sync" : "_async"); plot_name += string("_latency"); fNetTimeMon = new JackGnuPlotMonitor(128, 4, plot_name); string net_time_mon_fields[] = { string("sync send"), string("end of send"), string("sync recv"), string("end of cycle") }; string net_time_mon_options[] = { string("set xlabel \"audio cycles\""), string("set ylabel \"% of audio cycle\"") }; fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 4); #endif } JackNetMaster::~JackNetMaster() { jack_log("JackNetMaster::~JackNetMaster ID = %u", fParams.fID); if (fClient) { jack_deactivate(fClient); FreePorts(); jack_client_close(fClient); } delete[] fAudioCapturePorts; delete[] fAudioPlaybackPorts; delete[] fMidiCapturePorts; delete[] fMidiPlaybackPorts; #ifdef JACK_MONITOR fNetTimeMon->Save(); delete fNetTimeMon; #endif } //init-------------------------------------------------------------------------------- bool JackNetMaster::Init(bool auto_connect) { //network init if (!JackNetMasterInterface::Init()) { jack_error("JackNetMasterInterface::Init() error..."); return false; } //set global parameters if (!SetParams()) { jack_error("SetParams error..."); return false; } //jack client and process jack_status_t status; if ((fClient = jack_client_open(fName, JackNullOption, &status, NULL)) == NULL) { jack_error("Can't open a new JACK client"); return false; } if (jack_set_process_callback(fClient, SetProcess, this) < 0) { goto fail; } if (jack_set_buffer_size_callback(fClient, SetBufferSize, this) < 0) { goto fail; } if (jack_set_sample_rate_callback(fClient, SetSampleRate, this) < 0) { goto fail; } if (jack_set_latency_callback(fClient, LatencyCallback, this) < 0) { goto fail; } /* if (jack_set_port_connect_callback(fClient, SetConnectCallback, this) < 0) { goto fail; } */ if (AllocPorts() != 0) { jack_error("Can't allocate JACK ports"); goto fail; } //process can now run fRunning = true; //finally activate jack client if (jack_activate(fClient) != 0) { jack_error("Can't activate JACK client"); goto fail; } if (auto_connect) { ConnectPorts(); } jack_info("New NetMaster started"); return true; fail: FreePorts(); jack_client_close(fClient); fClient = NULL; return false; } //jack ports-------------------------------------------------------------------------- int JackNetMaster::AllocPorts() { int i; char name[32]; jack_log("JackNetMaster::AllocPorts"); //audio for (i = 0; i < fParams.fSendAudioChannels; i++) { snprintf(name, sizeof(name), "to_slave_%d", i+1); if ((fAudioCapturePorts[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0)) == NULL) { return -1; } } for (i = 0; i < fParams.fReturnAudioChannels; i++) { snprintf(name, sizeof(name), "from_slave_%d", i+1); if ((fAudioPlaybackPorts[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL) { return -1; } } //midi for (i = 0; i < fParams.fSendMidiChannels; i++) { snprintf(name, sizeof(name), "midi_to_slave_%d", i+1); if ((fMidiCapturePorts[i] = jack_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0)) == NULL) { return -1; } } for (i = 0; i < fParams.fReturnMidiChannels; i++) { snprintf(name, sizeof(name), "midi_from_slave_%d", i+1); if ((fMidiPlaybackPorts[i] = jack_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL) { return -1; } } return 0; } void JackNetMaster::ConnectPorts() { const char** ports = jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput); if (ports != NULL) { for (int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) { jack_connect(fClient, ports[i], jack_port_name(fAudioCapturePorts[i])); } jack_free(ports); } ports = jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput); if (ports != NULL) { for (int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) { jack_connect(fClient, jack_port_name(fAudioPlaybackPorts[i]), ports[i]); } jack_free(ports); } } void JackNetMaster::FreePorts() { jack_log("JackNetMaster::FreePorts ID = %u", fParams.fID); int port_index; for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { if (fAudioCapturePorts[port_index]) { jack_port_unregister(fClient, fAudioCapturePorts[port_index]); } } for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { if (fAudioPlaybackPorts[port_index]) { jack_port_unregister(fClient, fAudioPlaybackPorts[port_index]); } } for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { if (fMidiCapturePorts[port_index]) { jack_port_unregister(fClient, fMidiCapturePorts[port_index]); } } for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { if (fMidiPlaybackPorts[port_index]) { jack_port_unregister(fClient, fMidiPlaybackPorts[port_index]); } } } //transport--------------------------------------------------------------------------- void JackNetMaster::EncodeTransportData() { //is there a new timebase master ? //TODO : check if any timebase callback has been called (and if it's conditional or not) and set correct value... fSendTransportData.fTimebaseMaster = NO_CHANGE; //update state and position fSendTransportData.fState = static_cast(jack_transport_query(fClient, &fSendTransportData.fPosition)); //is it a new state ? fSendTransportData.fNewState = ((fSendTransportData.fState != fLastTransportState) && (fSendTransportData.fState != fReturnTransportData.fState)); if (fSendTransportData.fNewState) { jack_info("Sending '%s' to '%s' frame = %ld", GetTransportState(fSendTransportData.fState), fParams.fName, fSendTransportData.fPosition.frame); } fLastTransportState = fSendTransportData.fState; } void JackNetMaster::DecodeTransportData() { //is there timebase master change ? if (fReturnTransportData.fTimebaseMaster != NO_CHANGE) { int timebase = 0; switch (fReturnTransportData.fTimebaseMaster) { case RELEASE_TIMEBASEMASTER : timebase = jack_release_timebase(fClient); if (timebase < 0) { jack_error("Can't release timebase master"); } else { jack_info("'%s' isn't the timebase master anymore", fParams.fName); } break; case TIMEBASEMASTER : timebase = jack_set_timebase_callback(fClient, 0, SetTimebaseCallback, this); if (timebase < 0) { jack_error("Can't set a new timebase master"); } else { jack_info("'%s' is the new timebase master", fParams.fName); } break; case CONDITIONAL_TIMEBASEMASTER : timebase = jack_set_timebase_callback(fClient, 1, SetTimebaseCallback, this); if (timebase != EBUSY) { if (timebase < 0) jack_error("Can't set a new timebase master"); else jack_info("'%s' is the new timebase master", fParams.fName); } break; } } //is the slave in a new transport state and is this state different from master's ? if (fReturnTransportData.fNewState && (fReturnTransportData.fState != jack_transport_query(fClient, NULL))) { switch (fReturnTransportData.fState) { case JackTransportStopped : jack_transport_stop(fClient); jack_info("'%s' stops transport", fParams.fName); break; case JackTransportStarting : if (jack_transport_reposition(fClient, &fReturnTransportData.fPosition) == EINVAL) jack_error("Can't set new position"); jack_transport_start(fClient); jack_info("'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); break; case JackTransportNetStarting : jack_info("'%s' is ready to roll...", fParams.fName); break; case JackTransportRolling : jack_info("'%s' is rolling", fParams.fName); break; } } } void JackNetMaster::SetTimebaseCallback(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg) { static_cast(arg)->TimebaseCallback(pos); } void JackNetMaster::TimebaseCallback(jack_position_t* pos) { pos->bar = fReturnTransportData.fPosition.bar; pos->beat = fReturnTransportData.fPosition.beat; pos->tick = fReturnTransportData.fPosition.tick; pos->bar_start_tick = fReturnTransportData.fPosition.bar_start_tick; pos->beats_per_bar = fReturnTransportData.fPosition.beats_per_bar; pos->beat_type = fReturnTransportData.fPosition.beat_type; pos->ticks_per_beat = fReturnTransportData.fPosition.ticks_per_beat; pos->beats_per_minute = fReturnTransportData.fPosition.beats_per_minute; } //sync-------------------------------------------------------------------------------- bool JackNetMaster::IsSlaveReadyToRoll() { return (fReturnTransportData.fState == JackTransportNetStarting); } int JackNetMaster::SetBufferSize(jack_nframes_t nframes, void* arg) { JackNetMaster* obj = static_cast(arg); if (nframes != obj->fParams.fPeriodSize) { jack_error("Cannot currently handle buffer size change, so JackNetMaster proxy will be removed..."); obj->Exit(); } return 0; } int JackNetMaster::SetSampleRate(jack_nframes_t nframes, void* arg) { JackNetMaster* obj = static_cast(arg); if (nframes != obj->fParams.fSampleRate) { jack_error("Cannot currently handle sample rate change, so JackNetMaster proxy will be removed..."); obj->Exit(); } return 0; } void JackNetMaster::LatencyCallback(jack_latency_callback_mode_t mode, void* arg) { JackNetMaster* obj = static_cast(arg); jack_nframes_t port_latency = jack_get_buffer_size(obj->fClient); jack_latency_range_t range; //audio for (int i = 0; i < obj->fParams.fSendAudioChannels; i++) { //port latency range.min = range.max = float(obj->fParams.fNetworkLatency * port_latency) / 2.f; jack_port_set_latency_range(obj->fAudioCapturePorts[i], JackPlaybackLatency, &range); } //audio for (int i = 0; i < obj->fParams.fReturnAudioChannels; i++) { //port latency range.min = range.max = float(obj->fParams.fNetworkLatency * port_latency) / 2.f + ((obj->fParams.fSlaveSyncMode) ? 0 : port_latency); jack_port_set_latency_range(obj->fAudioPlaybackPorts[i], JackCaptureLatency, &range); } //midi for (int i = 0; i < obj->fParams.fSendMidiChannels; i++) { //port latency range.min = range.max = float(obj->fParams.fNetworkLatency * port_latency) / 2.f; jack_port_set_latency_range(obj->fMidiCapturePorts[i], JackPlaybackLatency, &range); } //midi for (int i = 0; i < obj->fParams.fReturnMidiChannels; i++) { //port latency range.min = range.max = obj->fParams.fNetworkLatency * port_latency + ((obj->fParams.fSlaveSyncMode) ? 0 : port_latency); jack_port_set_latency_range(obj->fMidiPlaybackPorts[i], JackCaptureLatency, &range); } } //process----------------------------------------------------------------------------- int JackNetMaster::SetProcess(jack_nframes_t nframes, void* arg) { try { return static_cast(arg)->Process(); } catch (JackNetException& e) { return 0; } } void JackNetMaster::SetConnectCallback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg) { static_cast(arg)->ConnectCallback(a, b, connect); } void JackNetMaster::ConnectCallback(jack_port_id_t a, jack_port_id_t b, int connect) { jack_info("JackNetMaster::ConnectCallback a = %d b = %d connect = %d", a, b, connect); if (connect) { jack_connect(fClient, jack_port_name(jack_port_by_id(fClient, a)), "system:playback_1"); } } int JackNetMaster::Process() { if (!fRunning) { return 0; } #ifdef JACK_MONITOR jack_time_t begin_time = GetMicroSeconds(); fNetTimeMon->New(); #endif //buffers for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { fNetMidiCaptureBuffer->SetBuffer(midi_port_index, static_cast(jack_port_get_buffer(fMidiCapturePorts[midi_port_index], fParams.fPeriodSize))); } for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { #ifdef OPTIMIZED_PROTOCOL if (fNetAudioCaptureBuffer->GetConnected(audio_port_index)) { // Port is connected on other side... fNetAudioCaptureBuffer->SetBuffer(audio_port_index, ((jack_port_connected(fAudioCapturePorts[audio_port_index]) > 0) ? static_cast(jack_port_get_buffer(fAudioCapturePorts[audio_port_index], fParams.fPeriodSize)) : NULL)); } else { fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL); } #else fNetAudioCaptureBuffer->SetBuffer(audio_port_index, static_cast(jack_port_get_buffer(fAudioCapturePorts[audio_port_index], fParams.fPeriodSize))); #endif // TODO } for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, static_cast(jack_port_get_buffer(fMidiPlaybackPorts[midi_port_index], fParams.fPeriodSize))); } for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) { #ifdef OPTIMIZED_PROTOCOL sample_t* out = (jack_port_connected(fAudioPlaybackPorts[audio_port_index]) > 0) ? static_cast(jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index], fParams.fPeriodSize)) : NULL; if (out) { memset(out, 0, sizeof(float) * fParams.fPeriodSize); } fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out); #else sample_t* out = static_cast(jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index], fParams.fPeriodSize)); if (out) { memset(out, 0, sizeof(float) * fParams.fPeriodSize); } fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out))); #endif } // encode the first packet EncodeSyncPacket(); if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; } #ifdef JACK_MONITOR fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); #endif // send data if (DataSend() == SOCKET_ERROR) { return SOCKET_ERROR; } #ifdef JACK_MONITOR fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); #endif // receive sync int res = SyncRecv(); switch (res) { case NET_SYNCHING: case SOCKET_ERROR: return res; case SYNC_PACKET_ERROR: // Since sync packet is incorrect, don't decode it and continue with data break; default: // Decode sync int unused_frames; DecodeSyncPacket(unused_frames); break; } #ifdef JACK_MONITOR fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); #endif // receive data res = DataRecv(); switch (res) { case 0: case SOCKET_ERROR: return res; case DATA_PACKET_ERROR: // Well not a real XRun... JackServerGlobals::fInstance->GetEngine()->NotifyClientXRun(ALL_CLIENTS); break; } #ifdef JACK_MONITOR fNetTimeMon->AddLast((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f); #endif return 0; } void JackNetMaster::SaveConnections(connections_list_t& connections) { // Audio for (int i = 0; i < fParams.fSendAudioChannels; i++) { const char** connected_port = jack_port_get_all_connections(fClient, fAudioCapturePorts[i]); if (connected_port != NULL) { for (int port = 0; connected_port[port]; port++) { connections.push_back(make_pair(connected_port[port], jack_port_name(fAudioCapturePorts[i]))); jack_log("INPUT %s ==> %s", connected_port[port], jack_port_name(fAudioCapturePorts[i])); } jack_free(connected_port); } } for (int i = 0; i < fParams.fReturnAudioChannels; i++) { const char** connected_port = jack_port_get_all_connections(fClient, fAudioPlaybackPorts[i]); if (connected_port != NULL) { for (int port = 0; connected_port[port]; port++) { connections.push_back(make_pair(jack_port_name(fAudioPlaybackPorts[i]), connected_port[port])); jack_log("OUTPUT %s ==> %s", jack_port_name(fAudioPlaybackPorts[i]), connected_port[port]); } jack_free(connected_port); } } // MIDI for (int i = 0; i < fParams.fSendMidiChannels; i++) { const char** connected_port = jack_port_get_all_connections(fClient, fMidiCapturePorts[i]); if (connected_port != NULL) { for (int port = 0; connected_port[port]; port++) { connections.push_back(make_pair(connected_port[port], jack_port_name(fMidiCapturePorts[i]))); jack_log("INPUT %s ==> %s", connected_port[port], jack_port_name(fMidiCapturePorts[i])); } jack_free(connected_port); } } for (int i = 0; i < fParams.fReturnMidiChannels; i++) { const char** connected_port = jack_port_get_all_connections(fClient, fMidiPlaybackPorts[i]); if (connected_port != NULL) { for (int port = 0; connected_port[port]; port++) { connections.push_back(make_pair(jack_port_name(fMidiPlaybackPorts[i]), connected_port[port])); jack_log("OUTPUT %s ==> %s", jack_port_name(fMidiPlaybackPorts[i]), connected_port[port]); } jack_free(connected_port); } } } void JackNetMaster::LoadConnections(const connections_list_t& connections) { list >::const_iterator it; for (it = connections.begin(); it != connections.end(); it++) { pair connection = *it; jack_connect(fClient, connection.first.c_str(), connection.second.c_str()); } } //JackNetMasterManager*********************************************************************************************** JackNetMasterManager::JackNetMasterManager(jack_client_t* client, const JSList* params) : fSocket() { jack_log("JackNetMasterManager::JackNetMasterManager"); fClient = client; fName = jack_get_client_name(fClient); fGlobalID = 0; fRunning = true; fAutoConnect = false; fAutoSave = false; const JSList* node; const jack_driver_param_t* param; jack_on_shutdown(fClient, SetShutDown, this); // Possibly use env variable const char* default_udp_port = getenv("JACK_NETJACK_PORT"); fSocket.SetPort((default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT); const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST"); if (default_multicast_ip) { strcpy(fMulticastIP, default_multicast_ip); } else { strcpy(fMulticastIP, DEFAULT_MULTICAST_IP); } for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'a' : if (strlen(param->value.str) < 32) { strcpy(fMulticastIP, param->value.str); } else { jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP); } break; case 'p': fSocket.SetPort(param->value.ui); break; case 'c': fAutoConnect = true; break; case 's': fAutoSave = true; break; } } //set sync callback jack_set_sync_callback(fClient, SetSyncCallback, this); //activate the client (for sync callback) if (jack_activate(fClient) != 0) { jack_error("Can't activate the NetManager client, transport disabled"); } //launch the manager thread if (jack_client_create_thread(fClient, &fThread, 0, 0, NetManagerThread, this)) { jack_error("Can't create the NetManager control thread"); } } JackNetMasterManager::~JackNetMasterManager() { jack_log("JackNetMasterManager::~JackNetMasterManager"); ShutDown(); } int JackNetMasterManager::CountIO(const char* type, int flags) { int count = 0; const char** ports = jack_get_ports(fClient, NULL, type, flags); if (ports != NULL) { while (ports[count]) { count++; } jack_free(ports); } return count; } void JackNetMasterManager::SetShutDown(void* arg) { static_cast(arg)->ShutDown(); } void JackNetMasterManager::ShutDown() { jack_log("JackNetMasterManager::ShutDown"); if (fRunning) { jack_client_kill_thread(fClient, fThread); fRunning = false; } master_list_t::iterator it; for (it = fMasterList.begin(); it != fMasterList.end(); it++) { delete (*it); } fMasterList.clear(); fSocket.Close(); SocketAPIEnd(); } int JackNetMasterManager::SetSyncCallback(jack_transport_state_t state, jack_position_t* pos, void* arg) { return static_cast(arg)->SyncCallback(state, pos); } int JackNetMasterManager::SyncCallback(jack_transport_state_t state, jack_position_t* pos) { //check if each slave is ready to roll int res = 1; master_list_it_t it; for (it = fMasterList.begin(); it != fMasterList.end(); it++) { if (!(*it)->IsSlaveReadyToRoll()) { res = 0; } } jack_log("JackNetMasterManager::SyncCallback returns '%s'", (res) ? "true" : "false"); return res; } void* JackNetMasterManager::NetManagerThread(void* arg) { JackNetMasterManager* master_manager = static_cast(arg); jack_info("Starting Jack NetManager"); jack_info("Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort()); master_manager->Run(); return NULL; } void JackNetMasterManager::Run() { jack_log("JackNetMasterManager::Run"); //utility variables int attempt = 0; //data session_params_t host_params; int rx_bytes = 0; JackNetMaster* net_master; //init socket API (win32) if (SocketAPIInit() < 0) { jack_error("Can't init Socket API, exiting..."); return; } //socket if (fSocket.NewSocket() == SOCKET_ERROR) { jack_error("Can't create NetManager input socket : %s", StrError(NET_ERROR_CODE)); return; } //bind the socket to the local port if (fSocket.Bind() == SOCKET_ERROR) { jack_error("Can't bind NetManager socket : %s", StrError(NET_ERROR_CODE)); fSocket.Close(); return; } //join multicast group if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) { jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE)); } //local loop if (fSocket.SetLocalLoop() == SOCKET_ERROR) { jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE)); } //set a timeout on the multicast receive (the thread can now be cancelled) if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) { jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE)); } //main loop, wait for data, deal with it and wait again do { session_params_t net_params; rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0); SessionParamsNToH(&net_params, &host_params); if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { jack_error("Error in receive : %s", StrError(NET_ERROR_CODE)); if (++attempt == 10) { jack_error("Can't receive on the socket, exiting net manager"); return; } } if (rx_bytes == sizeof(session_params_t)) { switch (GetPacketType(&host_params)) { case SLAVE_AVAILABLE: if ((net_master = InitMaster(host_params))) { SessionParamsDisplay(&net_master->fParams); } else { jack_error("Can't init new NetMaster..."); } jack_info("Waiting for a slave..."); break; case KILL_MASTER: if (KillMaster(&host_params)) { jack_info("Waiting for a slave..."); } break; default: break; } } } while (fRunning); } JackNetMaster* JackNetMasterManager::InitMaster(session_params_t& params) { jack_log("JackNetMasterManager::InitMaster slave : %s", params.fName); //check MASTER <<==> SLAVE network protocol coherency if (params.fProtocolVersion != NETWORK_PROTOCOL) { jack_error("Error : slave '%s' is running with a different protocol %d != %d", params.fName, params.fProtocolVersion, NETWORK_PROTOCOL); return NULL; } //settings fSocket.GetName(params.fMasterNetName); params.fID = ++fGlobalID; params.fSampleRate = jack_get_sample_rate(fClient); params.fPeriodSize = jack_get_buffer_size(fClient); if (params.fSendAudioChannels == -1) { params.fSendAudioChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput); jack_info("Takes physical %d audio input(s) for slave", params.fSendAudioChannels); } if (params.fReturnAudioChannels == -1) { params.fReturnAudioChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput); jack_info("Takes physical %d audio output(s) for slave", params.fReturnAudioChannels); } if (params.fSendMidiChannels == -1) { params.fSendMidiChannels = CountIO(JACK_DEFAULT_MIDI_TYPE, JackPortIsPhysical | JackPortIsOutput); jack_info("Takes physical %d MIDI input(s) for slave", params.fSendMidiChannels); } if (params.fReturnMidiChannels == -1) { params.fReturnMidiChannels = CountIO(JACK_DEFAULT_MIDI_TYPE, JackPortIsPhysical | JackPortIsInput); jack_info("Takes physical %d MIDI output(s) for slave", params.fReturnMidiChannels); } //create a new master and add it to the list JackNetMaster* master = new JackNetMaster(fSocket, params, fMulticastIP); if (master->Init(fAutoConnect)) { fMasterList.push_back(master); if (fAutoSave && fMasterConnectionList.find(params.fName) != fMasterConnectionList.end()) { master->LoadConnections(fMasterConnectionList[params.fName]); } return master; } else { delete master; return NULL; } } master_list_it_t JackNetMasterManager::FindMaster(uint32_t id) { jack_log("JackNetMasterManager::FindMaster ID = %u", id); master_list_it_t it; for (it = fMasterList.begin(); it != fMasterList.end(); it++) { if ((*it)->fParams.fID == id) { return it; } } return it; } int JackNetMasterManager::KillMaster(session_params_t* params) { jack_log("JackNetMasterManager::KillMaster ID = %u", params->fID); master_list_it_t master_it = FindMaster(params->fID); if (master_it != fMasterList.end()) { if (fAutoSave) { fMasterConnectionList[params->fName].clear(); (*master_it)->SaveConnections(fMasterConnectionList[params->fName]); } fMasterList.erase(master_it); delete (*master_it); return 1; } return 0; } }//namespace static Jack::JackNetMasterManager* master_manager = NULL; #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("netmanager", JackDriverNone, "netjack multi-cast master component", &filler); strcpy(value.str, DEFAULT_MULTICAST_IP); jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address", NULL); value.i = DEFAULT_PORT; jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "auto-connect", 'c', JackDriverParamBool, &value, NULL, "Auto connect netmaster to system ports", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "auto-save", 's', JackDriverParamBool, &value, NULL, "Save/restore netmaster connection state when restarted", NULL); return desc; } SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params) { if (master_manager) { jack_error("Master Manager already loaded"); return 1; } else { jack_log("Loading Master Manager"); master_manager = new Jack::JackNetMasterManager(jack_client, params); return (master_manager) ? 0 : 1; } } SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init) { JSList* params = NULL; bool parse_params = true; int res = 1; jack_driver_desc_t* desc = jack_get_descriptor(); Jack::JackArgParser parser(load_init); if (parser.GetArgc() > 0) { parse_params = parser.ParseParams(desc, ¶ms); } if (parse_params) { res = jack_internal_initialize(jack_client, params); parser.FreeParams(params); } return res; } SERVER_EXPORT void jack_finish(void* arg) { if (master_manager) { jack_log("Unloading Master Manager"); delete master_manager; master_manager = NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/common/JackWaitThreadedDriver.h0000644000000000000000000000557513214314510017327 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackWaitThreadedDriver__ #define __JackWaitThreadedDriver__ #include "JackThreadedDriver.h" #include "JackTimedDriver.h" namespace Jack { /*! \brief Wrapper for a restartable threaded driver (e.g. JackNetDriver). The idea is to behave as the "dummy" driver, until the network connection is really started and processing starts. The Execute method will call the ProcessNull method from the base JackWaiterDriver, until the decorated driver Initialize method returns. A helper JackDriverStarter thread is used for that purpose. */ class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver { private: struct JackDriverStarter : public JackRunnableInterface { JackDriver* fDriver; JackThread fThread; volatile bool fRunning; JackDriverStarter(JackDriver* driver) :fDriver(driver), fThread(this), fRunning(false) {} ~JackDriverStarter() { fThread.Kill(); } int Start() { fRunning = false; return fThread.Start(); } // JackRunnableInterface interface bool Execute() { // Blocks until decorated driver is started (that is when it's Initialize method returns). if (fDriver->Initialize()) { fRunning = true; } else { jack_error("Initing net driver fails..."); } return false; } }; JackDriverStarter fStarter; public: JackWaitThreadedDriver(JackDriver* net_driver) : JackThreadedDriver(net_driver), fStarter(net_driver) {} virtual ~JackWaitThreadedDriver() {} // JackRunnableInterface interface bool Init(); bool Execute(); protected: virtual bool ExecuteReal(); /*!< Real work to be done when the decorated driver has finish initializing */ }; } // end of namespace #endif 1.9.12~dfsg/common/JackResampler.cpp0000644000000000000000000000764013214314510016066 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackResampler.h" #include "JackError.h" #include namespace Jack { JackRingBuffer::JackRingBuffer(int size):fRingBufferSize(size) { fRingBuffer = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * fRingBufferSize); Reset(fRingBufferSize); } JackRingBuffer::~JackRingBuffer() { if (fRingBuffer) { jack_ringbuffer_free(fRingBuffer); } } void JackRingBuffer::Reset(unsigned int new_size) { fRingBufferSize = new_size; jack_ringbuffer_reset(fRingBuffer); jack_ringbuffer_reset_size(fRingBuffer, sizeof(jack_default_audio_sample_t) * fRingBufferSize); jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * new_size/2)); } unsigned int JackRingBuffer::ReadSpace() { return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(jack_default_audio_sample_t)); } unsigned int JackRingBuffer::WriteSpace() { return (jack_ringbuffer_write_space(fRingBuffer) / sizeof(jack_default_audio_sample_t)); } unsigned int JackRingBuffer::Read(jack_default_audio_sample_t* buffer, unsigned int frames) { size_t len = jack_ringbuffer_read_space(fRingBuffer); jack_log("JackRingBuffer::Read input available = %ld", len / sizeof(jack_default_audio_sample_t)); if (len < frames * sizeof(jack_default_audio_sample_t)) { jack_error("JackRingBuffer::Read : producer too slow, missing frames = %d", frames); return 0; } else { jack_ringbuffer_read(fRingBuffer, (char*)buffer, frames * sizeof(jack_default_audio_sample_t)); return frames; } } unsigned int JackRingBuffer::Write(jack_default_audio_sample_t* buffer, unsigned int frames) { size_t len = jack_ringbuffer_write_space(fRingBuffer); jack_log("JackRingBuffer::Write output available = %ld", len / sizeof(jack_default_audio_sample_t)); if (len < frames * sizeof(jack_default_audio_sample_t)) { jack_error("JackRingBuffer::Write : consumer too slow, skip frames = %d", frames); return 0; } else { jack_ringbuffer_write(fRingBuffer, (char*)buffer, frames * sizeof(jack_default_audio_sample_t)); return frames; } } unsigned int JackRingBuffer::Read(void* buffer, unsigned int bytes) { size_t len = jack_ringbuffer_read_space(fRingBuffer); jack_log("JackRingBuffer::Read input available = %ld", len); if (len < bytes) { jack_error("JackRingBuffer::Read : producer too slow, missing bytes = %d", bytes); return 0; } else { jack_ringbuffer_read(fRingBuffer, (char*)buffer, bytes); return bytes; } } unsigned int JackRingBuffer::Write(void* buffer, unsigned int bytes) { size_t len = jack_ringbuffer_write_space(fRingBuffer); jack_log("JackRingBuffer::Write output available = %ld", len); if (len < bytes) { jack_error("JackRingBuffer::Write : consumer too slow, skip bytes = %d", bytes); return 0; } else { jack_ringbuffer_write(fRingBuffer, (char*)buffer, bytes); return bytes; } } unsigned int JackResampler::ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames) { return Read(buffer, frames); } unsigned int JackResampler::WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames) { return Write(buffer, frames); } } 1.9.12~dfsg/common/JackEngineControl.h0000644000000000000000000001221313214314510016337 0ustar rootroot/* Copyright (C) 2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackEngineControl__ #define __JackEngineControl__ #include "JackShmMem.h" #include "JackFrameTimer.h" #include "JackTransportEngine.h" #include "JackConstants.h" #include "types.h" #include #ifdef JACK_MONITOR #include "JackEngineProfiling.h" #endif namespace Jack { class JackClientInterface; class JackGraphManager; #define JACK_ENGINE_ROLLING_COUNT 32 #define JACK_ENGINE_ROLLING_INTERVAL 1024 /*! \brief Engine control in shared memory. */ PRE_PACKED_STRUCTURE struct SERVER_EXPORT JackEngineControl : public JackShmMem { // Shared state jack_nframes_t fBufferSize; jack_nframes_t fSampleRate; bool fSyncMode; bool fTemporary; jack_time_t fPeriodUsecs; jack_time_t fTimeOutUsecs; float fMaxDelayedUsecs; float fXrunDelayedUsecs; bool fTimeOut; bool fRealTime; bool fSavedRealTime; // RT state saved and restored during Freewheel mode int fServerPriority; int fClientPriority; int fMaxClientPriority; char fServerName[JACK_SERVER_NAME_SIZE+1]; JackTransportEngine fTransport; jack_timer_type_t fClockSource; int fDriverNum; bool fVerbose; // CPU Load jack_time_t fPrevCycleTime; jack_time_t fCurCycleTime; jack_time_t fSpareUsecs; jack_time_t fMaxUsecs; jack_time_t fRollingClientUsecs[JACK_ENGINE_ROLLING_COUNT]; unsigned int fRollingClientUsecsCnt; int fRollingClientUsecsIndex; int fRollingInterval; float fCPULoad; // For OSX thread UInt64 fPeriod; UInt64 fComputation; UInt64 fConstraint; // Timer JackFrameTimer fFrameTimer; #ifdef JACK_MONITOR JackEngineProfiling fProfiler; #endif JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name) { fBufferSize = 512; fSampleRate = 48000; fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize); fSyncMode = sync; fTemporary = temporary; fTimeOut = (timeout > 0); fTimeOutUsecs = timeout * 1000; fRealTime = rt; fSavedRealTime = false; fServerPriority = priority; #ifdef WIN32 fClientPriority = (rt) ? priority - 3 : 0; #else fClientPriority = (rt) ? priority - 5 : 0; #endif fMaxClientPriority = (rt) ? priority - 1 : 0; fVerbose = verbose; fPrevCycleTime = 0; fCurCycleTime = 0; fSpareUsecs = 0; fMaxUsecs = 0; ResetRollingUsecs(); strncpy(fServerName, server_name, sizeof(fServerName)); fCPULoad = 0.f; fPeriod = 0; fComputation = 0; fConstraint = 0; fMaxDelayedUsecs = 0.f; fXrunDelayedUsecs = 0.f; fClockSource = clock; fDriverNum = 0; } ~JackEngineControl() {} void UpdateTimeOut() { fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize); // In microsec if (!(fTimeOut && fTimeOutUsecs > 2 * fPeriodUsecs)) { fTimeOutUsecs = 2 * fPeriodUsecs; } } // Cycle void CycleIncTime(jack_time_t callback_usecs) { // Timer fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs); } void CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { fTransport.CycleBegin(fSampleRate, cur_cycle_begin); CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end); #ifdef JACK_MONITOR fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end); #endif } void CycleEnd(JackClientInterface** table) { fTransport.CycleEnd(table, fSampleRate, fBufferSize); } // Timer void InitFrameTime() { fFrameTimer.InitFrameTime(); } void ResetFrameTime(jack_time_t callback_usecs) { fFrameTimer.ResetFrameTime(callback_usecs); } void ReadFrameTime(JackTimer* timer) { fFrameTimer.ReadFrameTime(timer); } // XRun void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); void ResetXRun() { fMaxDelayedUsecs = 0.f; } // Private void CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); void ResetRollingUsecs(); } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackActivationCount.cpp0000644000000000000000000000244313214314510017242 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackAtomic.h" #include "JackActivationCount.h" #include "JackConstants.h" #include "JackClientControl.h" #include "JackError.h" namespace Jack { bool JackActivationCount::Signal(JackSynchro* synchro, JackClientControl* control) { if (fValue == 0) { // Transfer activation to next clients jack_log("JackActivationCount::Signal value = 0 ref = %ld", control->fRefNum); return synchro->Signal(); } else if (DEC_ATOMIC(&fValue) == 1) { return synchro->Signal(); } else { return true; } } } // end of namespace 1.9.12~dfsg/common/JackMidiReceiveQueue.h0000644000000000000000000000206613214314510016770 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiReceiveQueue__ #define __JackMidiReceiveQueue__ #include "JackMidiReadQueue.h" namespace Jack { /** * Implemented by MIDI input connections. */ class SERVER_EXPORT JackMidiReceiveQueue: public JackMidiReadQueue { public: virtual ~JackMidiReceiveQueue(); }; } #endif 1.9.12~dfsg/common/JackException.cpp0000644000000000000000000000163213214314510016065 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackException.h" #include "JackError.h" namespace Jack { void JackException::PrintMessage() { std::string str = what(); if (str != "") { jack_info(str.c_str()); } } } 1.9.12~dfsg/common/JackMidiReadQueue.h0000644000000000000000000000277213214314510016265 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiReadQueue__ #define __JackMidiReadQueue__ #include "JackMidiPort.h" namespace Jack { /** * Interface for objects that MIDI events can be read from. */ class SERVER_EXPORT JackMidiReadQueue { public: virtual ~JackMidiReadQueue(); /** * Dequeues an event from the queue. Returns the event, or 0 if no * events are available for reading. * * An event dequeued from the read queue is guaranteed to be valid up * until another event is dequeued, at which all bets are off. Make * sure that you handle each event you dequeue before dequeueing the * next event. */ virtual jack_midi_event_t * DequeueEvent() = 0; }; } #endif 1.9.12~dfsg/common/JackShmMem.cpp0000644000000000000000000001002413214314510015310 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackError.h" #include "JackShmMem.h" #include namespace Jack { static unsigned int fSegmentNum = 0; static jack_shm_info_t gInfo; size_t JackMem::gSize = 0; JackShmMem::JackShmMem() { JackShmMemAble::Init(); LockMemory(); } JackShmMem::~JackShmMem() { UnlockMemory(); } void JackShmMemAble::Init() { fInfo.index = gInfo.index; fInfo.ptr.attached_at = gInfo.ptr.attached_at; fInfo.size = gInfo.size; } void* JackShmMem::operator new(size_t size, void* memory) { jack_log("JackShmMem::new placement size = %ld", size); return memory; } void* JackShmMem::operator new(size_t size) { jack_shm_info_t info; JackShmMem* obj; char name[64]; snprintf(name, sizeof(name), "/jack_shared%d", fSegmentNum++); if (jack_shmalloc(name, size, &info)) { jack_error("Cannot create shared memory segment of size = %d", size, strerror(errno)); goto error; } if (jack_attach_shm(&info)) { jack_error("Cannot attach shared memory segment name = %s err = %s", name, strerror(errno)); jack_destroy_shm(&info); goto error; } obj = (JackShmMem*)jack_shm_addr(&info); // It is unsafe to set object fields directly (may be overwritten during object initialization), // so use an intermediate global data gInfo.index = info.index; gInfo.size = size; gInfo.ptr.attached_at = info.ptr.attached_at; jack_log("JackShmMem::new index = %ld attached = %x size = %ld ", info.index, info.ptr.attached_at, size); return obj; error: jack_error("JackShmMem::new bad alloc", size); throw std::bad_alloc(); } void JackShmMem::operator delete(void* p, size_t size) { jack_shm_info_t info; JackShmMem* obj = (JackShmMem*)p; info.index = obj->fInfo.index; info.ptr.attached_at = obj->fInfo.ptr.attached_at; jack_log("JackShmMem::delete size = %ld index = %ld", size, info.index); jack_release_shm(&info); jack_destroy_shm(&info); } void JackShmMem::operator delete(void* obj) { if (obj) { JackShmMem::operator delete(obj, 0); } } void LockMemoryImp(void* ptr, size_t size) { if (CHECK_MLOCK((char*)ptr, size)) { jack_log("Succeeded in locking %u byte memory area", size); } else { jack_error("Cannot lock down %u byte memory area (%s)", size, strerror(errno)); } } void InitLockMemoryImp(void* ptr, size_t size) { if (CHECK_MLOCK((char*)ptr, size)) { memset(ptr, 0, size); jack_log("Succeeded in locking %u byte memory area", size); } else { jack_error("Cannot lock down %u byte memory area (%s)", size, strerror(errno)); } } void UnlockMemoryImp(void* ptr, size_t size) { if (CHECK_MUNLOCK((char*)ptr, size)) { jack_log("Succeeded in unlocking %u byte memory area", size); } else { jack_error("Cannot unlock down %u byte memory area (%s)", size, strerror(errno)); } } void LockAllMemory() { if (CHECK_MLOCKALL()) { jack_log("Succeeded in locking all memory"); } else { jack_error("Cannot lock all memory (%s)", strerror(errno)); } } void UnlockAllMemory() { if (CHECK_MUNLOCKALL()) { jack_log("Succeeded in unlocking all memory"); } else { jack_error("Cannot unlock all memory (%s)", strerror(errno)); } } } // end of namespace 1.9.12~dfsg/common/JackPort.h0000644000000000000000000000642113214314510014521 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPort__ #define __JackPort__ #include "types.h" #include "JackConstants.h" #include "JackCompilerDeps.h" namespace Jack { #define ALL_PORTS 0xFFFF #define NO_PORT 0xFFFE /*! \brief Base class for port. */ PRE_PACKED_STRUCTURE class SERVER_EXPORT JackPort { friend class JackGraphManager; private: int fTypeId; enum JackPortFlags fFlags; char fName[REAL_JACK_PORT_NAME_SIZE+1]; char fAlias1[REAL_JACK_PORT_NAME_SIZE+1]; char fAlias2[REAL_JACK_PORT_NAME_SIZE+1]; int fRefNum; jack_nframes_t fLatency; jack_nframes_t fTotalLatency; jack_latency_range_t fPlaybackLatency; jack_latency_range_t fCaptureLatency; uint8_t fMonitorRequests; bool fInUse; jack_port_id_t fTied; // Locally tied source port jack_default_audio_sample_t fBuffer[BUFFER_SIZE_MAX + 8]; bool IsUsed() const { return fInUse; } // RT void ClearBuffer(jack_nframes_t frames); void MixBuffers(void** src_buffers, int src_count, jack_nframes_t frames); public: JackPort(); bool Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags); void Release(); const char* GetName() const; const char* GetShortName() const; void SetName(const char* name); int GetAliases(char* const aliases[2]); int SetAlias(const char* alias); int UnsetAlias(const char* alias); bool NameEquals(const char* target); int GetFlags() const; const char* GetType() const; int Tie(jack_port_id_t port_index); int UnTie(); jack_nframes_t GetLatency() const; void SetLatency(jack_nframes_t latency); void SetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range); void GetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) const; jack_nframes_t GetTotalLatency() const; int RequestMonitor(bool onoff); int EnsureMonitor(bool onoff); bool MonitoringInput() { return (fMonitorRequests > 0); } // Since we are in shared memory, the resulting pointer cannot be cached, so align it here... jack_default_audio_sample_t* GetBuffer() { return (jack_default_audio_sample_t*)((uintptr_t)fBuffer & ~31L) + 8; } int GetRefNum() const; } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackAudioAdapter.cpp0000644000000000000000000001542313214314510016474 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioAdapter.h" #include "JackError.h" #include "JackCompilerDeps.h" #include "JackTools.h" #include "JackTime.h" #include "jslist.h" #include #include #include using namespace std; namespace Jack { int JackAudioAdapter::Process(jack_nframes_t frames, void* arg) { JackAudioAdapter* adapter = static_cast(arg); return adapter->ProcessAux(frames); } int JackAudioAdapter::ProcessAux(jack_nframes_t frames) { // Always clear output for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { fInputBufferList[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(fCapturePortList[i], frames); memset(fInputBufferList[i], 0, frames * sizeof(jack_default_audio_sample_t)); } for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { fOutputBufferList[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(fPlaybackPortList[i], frames); } fAudioAdapter->PullAndPush(fInputBufferList, fOutputBufferList, frames); return 0; } int JackAudioAdapter::BufferSize(jack_nframes_t buffer_size, void* arg) { JackAudioAdapter* adapter = static_cast(arg); adapter->Reset(); adapter->fAudioAdapter->SetHostBufferSize(buffer_size); return 0; } int JackAudioAdapter::SampleRate(jack_nframes_t sample_rate, void* arg) { JackAudioAdapter* adapter = static_cast(arg); adapter->Reset(); adapter->fAudioAdapter->SetHostSampleRate(sample_rate); return 0; } void JackAudioAdapter::Latency(jack_latency_callback_mode_t mode, void* arg) { JackAudioAdapter* adapter = static_cast(arg); if (mode == JackCaptureLatency) { for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { jack_latency_range_t range; range.min = range.max = adapter->fAudioAdapter->GetInputLatency(i); jack_port_set_latency_range(adapter->fCapturePortList[i], JackCaptureLatency, &range); } } else { for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { jack_latency_range_t range; range.min = range.max = adapter->fAudioAdapter->GetOutputLatency(i); jack_port_set_latency_range(adapter->fPlaybackPortList[i], JackPlaybackLatency, &range); } } } JackAudioAdapter::JackAudioAdapter(jack_client_t* client, JackAudioAdapterInterface* audio_io, const JSList* params) :fClient(client), fAudioAdapter(audio_io) { const JSList* node; const jack_driver_param_t* param; fAutoConnect = false; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*)node->data; switch (param->character) { case 'c': fAutoConnect = true; break; } } } JackAudioAdapter::~JackAudioAdapter() { // When called, Close has already been used for the client, thus ports are already unregistered. delete fAudioAdapter; } void JackAudioAdapter::FreePorts() { for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { if (fCapturePortList[i]) { jack_port_unregister(fClient, fCapturePortList[i]); } } for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { if (fPlaybackPortList[i]) { jack_port_unregister(fClient, fPlaybackPortList[i]); } } delete[] fCapturePortList; delete[] fPlaybackPortList; delete[] fInputBufferList; delete[] fOutputBufferList; } void JackAudioAdapter::ConnectPorts() { const char** ports; ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (ports != NULL) { for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) { jack_connect(fClient, jack_port_name(fCapturePortList[i]), ports[i]); } jack_free(ports); } ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); if (ports != NULL) { for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) { jack_connect(fClient, ports[i], jack_port_name(fPlaybackPortList[i])); } jack_free(ports); } } void JackAudioAdapter::Reset() { fAudioAdapter->Reset(); } int JackAudioAdapter::Open() { char name[32]; jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); fAudioAdapter->Create(); //jack ports fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; fInputBufferList = new jack_default_audio_sample_t*[fAudioAdapter->GetInputs()]; fOutputBufferList = new jack_default_audio_sample_t*[fAudioAdapter->GetOutputs()]; for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { snprintf(name, sizeof(name), "capture_%d", i + 1); if ((fCapturePortList[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, 0)) == NULL) { goto fail; } } for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { snprintf(name, sizeof(name), "playback_%d", i + 1); if ((fPlaybackPortList[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, 0)) == NULL) { goto fail; } } //callbacks and activation if (jack_set_process_callback(fClient, Process, this) < 0) { goto fail; } if (jack_set_buffer_size_callback(fClient, BufferSize, this) < 0) { goto fail; } if (jack_set_sample_rate_callback(fClient, SampleRate, this) < 0) { goto fail; } if (jack_set_latency_callback(fClient, Latency, this) < 0) { goto fail; } if (jack_activate(fClient) < 0) { goto fail; } if (fAutoConnect) { ConnectPorts(); } // Ring buffers are now allocated... return fAudioAdapter->Open(); return 0; fail: FreePorts(); fAudioAdapter->Destroy(); return -1; } int JackAudioAdapter::Close() { fAudioAdapter->Close(); fAudioAdapter->Destroy(); return 0; } } //namespace 1.9.12~dfsg/common/JackClientInterface.h0000644000000000000000000000252213214314510016632 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackClientInterface__ #define __JackClientInterface__ #include "JackCompilerDeps.h" namespace Jack { struct JackClientControl; /*! \brief Client interface. */ class SERVER_EXPORT JackClientInterface { public: JackClientInterface() {} virtual ~JackClientInterface() {} virtual int Close() = 0; virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) = 0; virtual JackClientControl* GetClientControl() const = 0; }; } // end of namespace #endif 1.9.12~dfsg/common/JackMidiDriver.cpp0000644000000000000000000001451113214314510016165 0ustar rootroot/* Copyright (C) 2009 Grame. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the (at your option) any later version. GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackMidiDriver.h" #include "JackTime.h" #include "JackError.h" #include "JackEngineControl.h" #include "JackPort.h" #include "JackGraphManager.h" #include "JackException.h" #include using namespace std; namespace Jack { JackMidiDriver::JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackDriver(name, alias, engine, table) {} JackMidiDriver::~JackMidiDriver() {} int JackMidiDriver::Open(bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { fCaptureChannels = inchannels; fPlaybackChannels = outchannels; return JackDriver::Open(0, 0, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } int JackMidiDriver::Attach() { JackPort* port; jack_port_id_t port_index; char name[REAL_JACK_PORT_NAME_SIZE+1]; char alias[REAL_JACK_PORT_NAME_SIZE+1]; int i; jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fCapturePortList[i] = port_index; jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } for (i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fPlaybackPortList[i] = port_index; jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } UpdateLatencies(); return 0; } int JackMidiDriver::Detach() { int i; jack_log("JackMidiDriver::Detach"); for (i = 0; i < fCaptureChannels; i++) { fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[i]); } for (i = 0; i < fPlaybackChannels; i++) { fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[i]); } return 0; } void JackMidiDriver::UpdateLatencies() { jack_latency_range_t range; for (int i = 0; i < fCaptureChannels; i++) { range.max = range.min = fEngineControl->fBufferSize; fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); } for (int i = 0; i < fPlaybackChannels; i++) { if (! fEngineControl->fSyncMode) { range.max = range.min = fEngineControl->fBufferSize * 2; } fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); } } int JackMidiDriver::SetBufferSize(jack_nframes_t buffer_size) { UpdateLatencies(); return 0; } int JackMidiDriver::ProcessReadSync() { int res = 0; // Read input buffers for the current cycle if (Read() < 0) { jack_error("JackMidiDriver::ProcessReadSync: read error"); res = -1; } if (ResumeRefNum() < 0) { jack_error("JackMidiDriver::ProcessReadSync: ResumeRefNum error"); res = -1; } return res; } int JackMidiDriver::ProcessWriteSync() { int res = 0; if (SuspendRefNum() < 0) { jack_error("JackMidiDriver::ProcessWriteSync: SuspendRefNum error"); res = -1; } // Write output buffers from the current cycle if (Write() < 0) { jack_error("JackMidiDriver::ProcessWriteSync: write error"); res = -1; } return res; } int JackMidiDriver::ProcessReadAsync() { int res = 0; // Read input buffers for the current cycle if (Read() < 0) { jack_error("JackMidiDriver::ProcessReadAsync: read error"); res = -1; } // Write output buffers from the previous cycle if (Write() < 0) { jack_error("JackMidiDriver::ProcessReadAsync: write error"); res = -1; } if (ResumeRefNum() < 0) { jack_error("JackMidiDriver::ProcessReadAsync: ResumeRefNum error"); res = -1; } return res; } int JackMidiDriver::ProcessWriteAsync() { return 0; } JackMidiBuffer* JackMidiDriver::GetInputBuffer(int port_index) { assert(fCapturePortList[port_index]); return (JackMidiBuffer*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize); } JackMidiBuffer* JackMidiDriver::GetOutputBuffer(int port_index) { assert(fPlaybackPortList[port_index]); return (JackMidiBuffer*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize); } } // end of namespace 1.9.12~dfsg/common/memops.h0000644000000000000000000002003213214314510014276 0ustar rootroot/* Copyright (C) 1999-2000 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __jack_memops_h__ #define __jack_memops_h__ #include "types.h" #ifdef __cplusplus extern "C" { #endif #ifdef sun #define __inline__ #endif typedef enum { None, Rectangular, Triangular, Shaped } DitherAlgorithm; #define DITHER_BUF_SIZE 8 #define DITHER_BUF_MASK 7 typedef struct { unsigned int depth; float rm1; unsigned int idx; float e[DITHER_BUF_SIZE]; } dither_state_t; /* float functions */ void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long dst_skip); void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); /* integer functions */ void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_rect_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_rect_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_tri_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_tri_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_shaped_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_shaped_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_rect_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_rect_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_tri_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_shaped_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_rect_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_merge_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); static __inline__ void sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) { while (cnt--) { *dst += *src; dst++; src++; } } static __inline__ void sample_memcpy (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) { memcpy (dst, src, cnt * sizeof (jack_default_audio_sample_t)); } void memset_interleave (char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes); void memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); void memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); void memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); void memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); void merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); void merge_memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); void merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); void merge_memcpy_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); void merge_memcpy_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); #ifdef __cplusplus } #endif #endif /* __jack_memops_h__ */ 1.9.12~dfsg/common/JackGenericClientChannel.cpp0000644000000000000000000002254113214314510020135 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackGenericClientChannel.h" #include "JackClient.h" #include "JackGlobals.h" #include "JackError.h" namespace Jack { JackGenericClientChannel::JackGenericClientChannel() {} JackGenericClientChannel::~JackGenericClientChannel() {} int JackGenericClientChannel::ServerCheck(const char* server_name) { jack_log("JackGenericClientChannel::ServerCheck = %s", server_name); // Connect to server if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) { jack_error("Cannot connect to server request channel"); return -1; } else { return 0; } } void JackGenericClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, int* result) { // Check call context if (jack_tls_get(JackGlobals::fNotificationThread)) { jack_error("Cannot callback the server in notification thread!"); *result = -1; return; } if (!JackGlobals::fServerRunning) { jack_error("Server is not running"); *result = -1; return; } if (req->Write(fRequest) < 0) { jack_error("Could not write request type = %ld", req->fType); *result = -1; return; } if (res->Read(fRequest) < 0) { jack_error("Could not read result type = %ld", req->fType); *result = -1; return; } *result = res->fResult; } void JackGenericClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, int* result) { // Check call context if (jack_tls_get(JackGlobals::fNotificationThread)) { jack_error("Cannot callback the server in notification thread!"); *result = -1; return; } if (!JackGlobals::fServerRunning) { jack_error("Server is not running"); *result = -1; return; } if (req->Write(fRequest) < 0) { jack_error("Could not write request type = %ld", req->fType); *result = -1; } else { *result = 0; } } void JackGenericClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open) { JackClientCheckRequest req(name, protocol, options, uuid, open); JackClientCheckResult res; ServerSyncCall(&req, &res, result); *status |= res.fStatus; strcpy(name_res, res.fName); } void JackGenericClientChannel::ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) { JackClientOpenRequest req(name, pid, uuid); JackClientOpenResult res; ServerSyncCall(&req, &res, result); *shared_engine = res.fSharedEngine; *shared_client = res.fSharedClient; *shared_graph = res.fSharedGraph; } void JackGenericClientChannel::ClientClose(int refnum, int* result) { JackClientCloseRequest req(refnum); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::ClientActivate(int refnum, int is_real_time, int* result) { JackActivateRequest req(refnum, is_real_time); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::ClientDeactivate(int refnum, int* result) { JackDeactivateRequest req(refnum); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) { JackPortRegisterRequest req(refnum, name, type, flags, buffer_size); JackPortRegisterResult res; ServerSyncCall(&req, &res, result); *port_index = res.fPortIndex; } void JackGenericClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result) { JackPortUnRegisterRequest req(refnum, port_index); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result) { JackPortConnectNameRequest req(refnum, src, dst); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result) { JackPortDisconnectNameRequest req(refnum, src, dst); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) { JackPortConnectRequest req(refnum, src, dst); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) { JackPortDisconnectRequest req(refnum, src, dst); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::PortRename(int refnum, jack_port_id_t port, const char* name, int* result) { JackPortRenameRequest req(refnum, port, name); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result) { JackSetBufferSizeRequest req(buffer_size); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::SetFreewheel(int onoff, int* result) { JackSetFreeWheelRequest req(onoff); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::ComputeTotalLatencies(int* result) { JackComputeTotalLatenciesRequest req; JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) { JackSessionNotifyRequest req(refnum, path, type, target); JackSessionNotifyResult res; int intresult; ServerSyncCall(&req, &res, &intresult); *result = res.GetCommands(); } void JackGenericClientChannel::SessionReply(int refnum, int* result) { JackSessionReplyRequest req(refnum); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result) { JackGetUUIDRequest req(client_name); JackUUIDResult res; ServerSyncCall(&req, &res, result); strncpy(uuid_res, res.fUUID, JACK_UUID_SIZE); } void JackGenericClientChannel::GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result) { JackGetClientNameRequest req(uuid); JackClientNameResult res; ServerSyncCall(&req, &res, result); strncpy(name_res, res.fName, JACK_CLIENT_NAME_SIZE); } void JackGenericClientChannel::ClientHasSessionCallback(const char* client_name, int* result) { JackClientHasSessionCallbackRequest req(client_name); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::ReserveClientName(int refnum, const char* client_name, const char* uuid, int* result) { JackReserveNameRequest req(refnum, client_name, uuid); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::ReleaseTimebase(int refnum, int* result) { JackReleaseTimebaseRequest req(refnum); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result) { JackSetTimebaseCallbackRequest req(refnum, conditional); JackResult res; ServerSyncCall(&req, &res, result); } void JackGenericClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) { JackGetInternalClientNameRequest req(refnum, int_ref); JackGetInternalClientNameResult res; ServerSyncCall(&req, &res, result); strcpy(name_res, res.fName); } void JackGenericClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result) { JackInternalClientHandleRequest req(refnum, client_name); JackInternalClientHandleResult res; ServerSyncCall(&req, &res, result); *int_ref = res.fIntRefNum; *status = res.fStatus; } void JackGenericClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) { JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options, uuid); JackInternalClientLoadResult res; ServerSyncCall(&req, &res, result); *int_ref = res.fIntRefNum; *status = res.fStatus; } void JackGenericClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result) { JackInternalClientUnloadRequest req(refnum, int_ref); JackInternalClientUnloadResult res; ServerSyncCall(&req, &res, result); *status = res.fStatus; } } // end of namespace 1.9.12~dfsg/common/JackTools.h0000644000000000000000000001464413214314510014703 0ustar rootroot/* Copyright (C) 2006-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackTools__ #define __JackTools__ #ifdef WIN32 #include #define DIR_SEPARATOR '\\' #else #define DIR_SEPARATOR '/' #include #include #include #include #endif #ifdef __APPLE__ #include #endif #include "jslist.h" #include "JackCompilerDeps.h" #include "JackError.h" #include #include #include #include #include namespace Jack { /*! \brief Utility functions. */ struct SERVER_EXPORT JackTools { static int GetPID(); static int GetUID(); static void KillServer(); static int MkDir(const char* path); static char* UserDir(); static char* ServerDir(const char* server_name, char* server_dir); static const char* DefaultServerName(); static void CleanupFiles(const char* server_name); static int GetTmpdir(); static void RewriteName(const char* name, char* new_name); static void ThrowJackNetException(); // For OSX only static int ComputationMicroSec(int buffer_size) { if (buffer_size < 128) { return 500; } else if (buffer_size < 256) { return 300; } else { return 100; } } }; /*! \brief Generic monitoring class. Saves data to GnuPlot files ('.plt' and '.log' datafile) This template class allows to manipulate monitoring records, and automatically generate the GnuPlot config and data files. Operations are RT safe because it uses fixed size data buffers. You can set the number of measure points, and the number of records. To use it : - create a JackGnuPlotMonitor, you can use the data type you want. - create a temporary array for your measure - once you have filled this array with 'measure points' value, call write() to add it to the record - once you've done with your measurment, just call save() to save your data file You can also call SetPlotFile() to automatically generate '.plt' file from an options list. */ template class JackGnuPlotMonitor { private: uint32_t fMeasureCnt; uint32_t fMeasurePoints; uint32_t fMeasureId; T* fCurrentMeasure; T** fMeasureTable; uint32_t fTablePos; std::string fName; public: JackGnuPlotMonitor(uint32_t measure_cnt, uint32_t measure_points, std::string name) { jack_log ( "JackGnuPlotMonitor::JackGnuPlotMonitor %u measure points - %u measures", measure_points, measure_cnt ); fMeasureCnt = measure_cnt; fMeasurePoints = measure_points; fTablePos = 0; fName = name; fCurrentMeasure = new T[fMeasurePoints]; fMeasureTable = new T*[fMeasureCnt]; for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ ) { fMeasureTable[cnt] = new T[fMeasurePoints]; std::fill_n ( fMeasureTable[cnt], fMeasurePoints, 0 ); } } ~JackGnuPlotMonitor() { jack_log ( "JackGnuPlotMonitor::~JackGnuPlotMonitor" ); for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ ) delete[] fMeasureTable[cnt]; delete[] fMeasureTable; delete[] fCurrentMeasure; } T AddNew(T measure_point) { fMeasureId = 0; return fCurrentMeasure[fMeasureId++] = measure_point; } uint32_t New() { return fMeasureId = 0; } T Add(T measure_point) { return fCurrentMeasure[fMeasureId++] = measure_point; } uint32_t AddLast(T measure_point) { fCurrentMeasure[fMeasureId] = measure_point; fMeasureId = 0; return Write(); } uint32_t Write() { for ( uint32_t point = 0; point < fMeasurePoints; point++ ) fMeasureTable[fTablePos][point] = fCurrentMeasure[point]; if ( ++fTablePos == fMeasureCnt ) fTablePos = 0; return fTablePos; } int Save(std::string name = std::string ( "" )) { std::string filename = ( name.empty() ) ? fName : name; filename += ".log"; jack_log ( "JackGnuPlotMonitor::Save filename %s", filename.c_str() ); std::ofstream file ( filename.c_str() ); for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ ) { for ( uint32_t point = 0; point < fMeasurePoints; point++ ) file << fMeasureTable[cnt][point] << " \t"; file << std::endl; } file.close(); return 0; } int SetPlotFile(std::string* options_list, uint32_t options_number, std::string* field_names, uint32_t field_number, std::string name = std::string ( "" )) { std::string title = ( name.empty() ) ? fName : name; std::string plot_filename = title + ".plt"; std::string data_filename = title + ".log"; std::ofstream file ( plot_filename.c_str() ); file << "set multiplot" << std::endl; file << "set grid" << std::endl; file << "set title \"" << title << "\"" << std::endl; for ( uint32_t i = 0; i < options_number; i++ ) file << options_list[i] << std::endl; file << "plot "; for ( uint32_t row = 1; row <= field_number; row++ ) { file << "\"" << data_filename << "\" using " << row << " title \"" << field_names[row-1] << "\" with lines"; file << ( ( row < field_number ) ? ", " : "\n" ); } jack_log ( "JackGnuPlotMonitor::SetPlotFile - Save GnuPlot file to '%s'", plot_filename.c_str() ); file.close(); return 0; } }; void BuildClientPath(char* path_to_so, int path_len, const char* so_name); void PrintLoadError(const char* so_name); } #endif 1.9.12~dfsg/common/JackMidiRawInputWriteQueue.h0000644000000000000000000001325713214314510020176 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiRawInputWriteQueue__ #define __JackMidiRawInputWriteQueue__ #include "JackMidiAsyncQueue.h" #include "JackMidiWriteQueue.h" namespace Jack { /** * This queue enqueues raw, unparsed MIDI packets, and outputs complete * MIDI messages to a write queue. * * Use this queue if the MIDI API you're interfacing with gives you raw * MIDI bytes that must be parsed. */ class SERVER_EXPORT JackMidiRawInputWriteQueue: public JackMidiWriteQueue { private: jack_midi_event_t event; jack_midi_data_t event_byte; bool event_pending; size_t expected_bytes; jack_midi_data_t *input_buffer; size_t input_buffer_size; jack_midi_event_t *packet; JackMidiAsyncQueue *packet_queue; jack_midi_data_t status_byte; size_t total_bytes; size_t unbuffered_bytes; JackMidiWriteQueue *write_queue; void Clear(); bool PrepareBufferedEvent(jack_nframes_t time); bool PrepareByteEvent(jack_nframes_t time, jack_midi_data_t byte); void PrepareEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); bool ProcessByte(jack_nframes_t time, jack_midi_data_t byte); void RecordByte(jack_midi_data_t byte); bool WriteEvent(jack_nframes_t boundary_frame); protected: /** * Override this method to specify what happens when there isn't enough * room in the ringbuffer to contain a parsed event. The default * method outputs an error message. */ virtual void HandleBufferFailure(size_t unbuffered_bytes, size_t total_bytes); /** * Override this method to specify what happens when a parsed event * can't be written to the write queue because the event's size exceeds * the total possible space in the write queue. The default method * outputs an error message. */ virtual void HandleEventLoss(jack_midi_event_t *event); /** * Override this method to specify what happens when an incomplete MIDI * message is parsed. The default method outputs an error message. */ virtual void HandleIncompleteMessage(size_t total_bytes); /** * Override this method to specify what happens when an invalid MIDI * status byte is parsed. The default method outputs an error message. */ virtual void HandleInvalidStatusByte(jack_midi_data_t byte); /** * Override this method to specify what happens when a sysex end byte * is parsed without first parsing a sysex begin byte. The default * method outputs an error message. */ virtual void HandleUnexpectedSysexEnd(size_t total_bytes); public: using JackMidiWriteQueue::EnqueueEvent; /** * Called to create a new raw input write queue. The `write_queue` * argument is the queue to write parsed messages to. The optional * `max_packets` argument specifies the number of packets that can be * enqueued in the internal queue. The optional `max_packet_data` * argument specifies the total number of MIDI bytes that can be put in * the internal queue, AND the maximum size for an event that can be * written to the write queue. */ JackMidiRawInputWriteQueue(JackMidiWriteQueue *write_queue, size_t max_packet_data=4096, size_t max_packets=1024); ~JackMidiRawInputWriteQueue(); EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); /** * Returns the maximum size event that can be enqueued right *now*. */ size_t GetAvailableSpace(); /** * The `Process()` method should be called each time the * `EnqueueEvent()` method returns `OK`. The `Process()` method will * return the next frame at which an event should be sent. The return * value from `Process()` depends upon the result of writing bytes to * the write queue: * * -If the return value is '0', then all *complete* events have been * sent successfully to the write queue. Don't call `Process()` again * until another event has been enqueued. * * -If the return value is a non-zero value, then it specifies the * frame that a pending event is scheduled to sent at. If the frame is * in the future, then `Process()` should be called again at that time; * otherwise, `Process()` should be called as soon as the write queue * will accept events again. */ jack_nframes_t Process(jack_nframes_t boundary_frame=0); }; } #endif 1.9.12~dfsg/common/JackNetInterface.h0000644000000000000000000001610213214314510016141 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackNetInterface__ #define __JackNetInterface__ #include "JackNetTool.h" #include namespace Jack { #define DEFAULT_MULTICAST_IP "225.3.19.154" #define DEFAULT_PORT 19000 #define DEFAULT_MTU 1500 #define MAX_MTU 9000 #define SLAVE_SETUP_RETRY 5 #define MANAGER_INIT_TIMEOUT 1000000 * 2 // in usec #define MASTER_INIT_TIMEOUT 1000000 * 10 // in usec #define SLAVE_INIT_TIMEOUT 1000000 * 1 // in usec #define PACKET_TIMEOUT 1000000 // in usec #define NETWORK_DEFAULT_LATENCY 2 #define NETWORK_MAX_LATENCY 30 // maximum possible latency in network master/slave loop /** \Brief This class describes the basic Net Interface, used by both master and slave. */ class SERVER_EXPORT JackNetInterface { friend class JackNetExt; protected: bool fSetTimeOut; int fPacketTimeOut; void Initialize(); session_params_t fParams; JackNetSocket fSocket; char fMulticastIP[32]; // headers packet_header_t fTxHeader; packet_header_t fRxHeader; // transport net_transport_data_t fSendTransportData; net_transport_data_t fReturnTransportData; // network buffers char* fTxBuffer; char* fRxBuffer; char* fTxData; char* fRxData; // JACK buffers NetMidiBuffer* fNetMidiCaptureBuffer; NetMidiBuffer* fNetMidiPlaybackBuffer; NetAudioBuffer* fNetAudioCaptureBuffer; NetAudioBuffer* fNetAudioPlaybackBuffer; // utility methods int SetNetBufferSize(); void FreeNetworkBuffers(); // virtual methods : depends on the sub class master/slave virtual bool SetParams(); virtual bool Init() = 0; // transport virtual void EncodeTransportData() = 0; virtual void DecodeTransportData() = 0; // sync packet virtual void EncodeSyncPacket(int frames = -1) = 0; virtual void DecodeSyncPacket(int& frames) = 0; virtual int SyncRecv() = 0; virtual int SyncSend() = 0; virtual int DataRecv() = 0; virtual int DataSend() = 0; virtual int Send(size_t size, int flags) = 0; virtual int Recv(size_t size, int flags) = 0; virtual void FatalRecvError() = 0; virtual void FatalSendError() = 0; int MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels); int AudioSend(NetAudioBuffer* buffer, int audio_channels); int MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt); int AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer); int FinishRecv(NetAudioBuffer* buffer); void SetRcvTimeOut(); void SetPacketTimeOut(int time_out) { // New time out fPacketTimeOut = time_out; fSetTimeOut = false; } NetAudioBuffer* AudioBufferFactory(int nports, char* buffer); public: JackNetInterface(); JackNetInterface(const char* multicast_ip, int port); JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip); virtual ~JackNetInterface(); }; /** \Brief This class describes the Net Interface for masters (NetMaster) */ class SERVER_EXPORT JackNetMasterInterface : public JackNetInterface { protected: bool fRunning; int fCurrentCycleOffset; int fMaxCycleOffset; bool fSynched; bool Init(); bool SetParams(); void Exit(); int SyncRecv(); int SyncSend(); int DataRecv(); int DataSend(); // sync packet void EncodeSyncPacket(int frames = -1); void DecodeSyncPacket(int& frames); int Send(size_t size, int flags); int Recv(size_t size, int flags); void FatalRecvError(); void FatalSendError(); public: JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCurrentCycleOffset(0), fMaxCycleOffset(0), fSynched(false) {} JackNetMasterInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip) : JackNetInterface(params, socket, multicast_ip), fRunning(false), fCurrentCycleOffset(0), fMaxCycleOffset(0), fSynched(false) {} virtual~JackNetMasterInterface() {} }; /** \Brief This class describes the Net Interface for slaves (NetDriver and NetAdapter) */ class SERVER_EXPORT JackNetSlaveInterface : public JackNetInterface { protected: static uint fSlaveCounter; bool Init(); bool InitConnection(int time_out_sec); bool InitRendering(); net_status_t SendAvailableToMaster(int count = INT_MAX); net_status_t SendStartToMaster(); bool SetParams(); int SyncRecv(); int SyncSend(); int DataRecv(); int DataSend(); // sync packet void EncodeSyncPacket(int frames = -1); void DecodeSyncPacket(int& frames); int Recv(size_t size, int flags); int Send(size_t size, int flags); void FatalRecvError(); void FatalSendError(); void InitAPI(); public: JackNetSlaveInterface() : JackNetInterface() { InitAPI(); } JackNetSlaveInterface(const char* ip, int port) : JackNetInterface(ip, port) { InitAPI(); } virtual ~JackNetSlaveInterface() { // close Socket API with the last slave if (--fSlaveCounter == 0) { SocketAPIEnd(); } } }; } #endif 1.9.12~dfsg/common/JackProxyDriver.h0000644000000000000000000002357713214314510016105 0ustar rootroot/* Copyright (C) 2014 Cédric Schieli This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __JackProxyDriver__ #define __JackProxyDriver__ #include "JackTimedDriver.h" #define DEFAULT_UPSTREAM "default" /*!< Default upstream Jack server to connect to */ #define DEFAULT_CLIENT_NAME "proxy" /*!< Default client name to use when connecting to upstream Jack server */ #ifdef __APPLE__ #define JACK_PROXY_CLIENT_LIB "libjack.0.dylib" #elif defined(WIN32) #ifdef _WIN64 #define JACK_PROXY_CLIENT_LIB "libjack64.dll" #else #define JACK_PROXY_CLIENT_LIB "libjack.dll" #endif #else #define JACK_PROXY_CLIENT_LIB "libjack.so.0" #endif #define PROXY_DEF_SYMBOL(ret,name,...) ret (*name) (__VA_ARGS__) #define PROXY_LOAD_SYMBOL(ret,name,...) name = (ret (*) (__VA_ARGS__)) GetJackProc(fHandle, #name); assert(name) namespace Jack { /*! \Brief This class describes the Proxy Backend It uses plain Jack API to connect to an upstream server. The latter is either running as the same user, or is running in promiscuous mode. The main use case is the multi-user, multi-session, shared workstation: - a classic server with hw driver is launched system-wide at boot time, in promiscuous mode, optionaly restricted to the audio group - in each user session, a jackdbus server is automatically started with JackProxyDriver as master driver, automatically connected to the system-wide one - optionaly, each user run PulseAudio with a pulse-jack bridge */ class JackProxyDriver : public JackRestarterDriver { private: char fUpstream[JACK_CLIENT_NAME_SIZE+1]; /* #include #include #include namespace Jack { static void AssertBufferSize(jack_nframes_t buffer_size) { if (buffer_size > BUFFER_SIZE_MAX) { jack_log("JackGraphManager::AssertBufferSize frames = %ld", buffer_size); assert(buffer_size <= BUFFER_SIZE_MAX); } } void JackGraphManager::AssertPort(jack_port_id_t port_index) { if (port_index >= fPortMax) { jack_log("JackGraphManager::AssertPort port_index = %ld", port_index); assert(port_index < fPortMax); } } JackGraphManager* JackGraphManager::Allocate(int port_max) { // Using "Placement" new void* shared_ptr = JackShmMem::operator new(sizeof(JackGraphManager) + port_max * sizeof(JackPort)); return new(shared_ptr) JackGraphManager(port_max); } void JackGraphManager::Destroy(JackGraphManager* manager) { // "Placement" new was used manager->~JackGraphManager(); JackShmMem::operator delete(manager); } JackGraphManager::JackGraphManager(int port_max) { assert(port_max <= PORT_NUM_MAX); for (int i = 0; i < port_max; i++) { fPortArray[i].Release(); } fPortMax = port_max; } JackPort* JackGraphManager::GetPort(jack_port_id_t port_index) { AssertPort(port_index); return &fPortArray[port_index]; } jack_default_audio_sample_t* JackGraphManager::GetBuffer(jack_port_id_t port_index) { return fPortArray[port_index].GetBuffer(); } // Server void JackGraphManager::InitRefNum(int refnum) { JackConnectionManager* manager = WriteNextStateStart(); manager->InitRefNum(refnum); WriteNextStateStop(); } // RT void JackGraphManager::RunCurrentGraph() { JackConnectionManager* manager = ReadCurrentState(); manager->ResetGraph(fClientTiming); } // RT bool JackGraphManager::RunNextGraph() { bool res; JackConnectionManager* manager = TrySwitchState(&res); manager->ResetGraph(fClientTiming); return res; } // RT bool JackGraphManager::IsFinishedGraph() { JackConnectionManager* manager = ReadCurrentState(); return (manager->GetActivation(FREEWHEEL_DRIVER_REFNUM) == 0); } // RT int JackGraphManager::ResumeRefNum(JackClientControl* control, JackSynchro* table) { JackConnectionManager* manager = ReadCurrentState(); return manager->ResumeRefNum(control, table, fClientTiming); } // RT int JackGraphManager::SuspendRefNum(JackClientControl* control, JackSynchro* table, long usec) { JackConnectionManager* manager = ReadCurrentState(); return manager->SuspendRefNum(control, table, fClientTiming, usec); } void JackGraphManager::TopologicalSort(std::vector& sorted) { UInt16 cur_index; UInt16 next_index; do { cur_index = GetCurrentIndex(); sorted.clear(); ReadCurrentState()->TopologicalSort(sorted); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read } // Server void JackGraphManager::DirectConnect(int ref1, int ref2) { JackConnectionManager* manager = WriteNextStateStart(); manager->DirectConnect(ref1, ref2); jack_log("JackGraphManager::ConnectRefNum cur_index = %ld ref1 = %ld ref2 = %ld", CurIndex(fCounter), ref1, ref2); WriteNextStateStop(); } // Server void JackGraphManager::DirectDisconnect(int ref1, int ref2) { JackConnectionManager* manager = WriteNextStateStart(); manager->DirectDisconnect(ref1, ref2); jack_log("JackGraphManager::DisconnectRefNum cur_index = %ld ref1 = %ld ref2 = %ld", CurIndex(fCounter), ref1, ref2); WriteNextStateStop(); } // Server bool JackGraphManager::IsDirectConnection(int ref1, int ref2) { JackConnectionManager* manager = ReadCurrentState(); return manager->IsDirectConnection(ref1, ref2); } // RT void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buffer_size) { AssertPort(port_index); AssertBufferSize(buffer_size); JackConnectionManager* manager = ReadCurrentState(); JackPort* port = GetPort(port_index); // This happens when a port has just been unregistered and is still used by the RT code if (!port->IsUsed()) { jack_log("JackGraphManager::GetBuffer : port = %ld is released state", port_index); return GetBuffer(0); // port_index 0 is not used } jack_int_t len = manager->Connections(port_index); // Output port if (port->fFlags & JackPortIsOutput) { return (port->fTied != NO_PORT) ? GetBuffer(port->fTied, buffer_size) : GetBuffer(port_index); } // No connections : return a zero-filled buffer if (len == 0) { port->ClearBuffer(buffer_size); return port->GetBuffer(); // One connection } else if (len == 1) { jack_port_id_t src_index = manager->GetPort(port_index, 0); // Ports in same client : copy the buffer if (GetPort(src_index)->GetRefNum() == port->GetRefNum()) { void* buffers[1]; buffers[0] = GetBuffer(src_index, buffer_size); port->MixBuffers(buffers, 1, buffer_size); return port->GetBuffer(); // Otherwise, use zero-copy mode, just pass the buffer of the connected (output) port. } else { return GetBuffer(src_index, buffer_size); } // Multiple connections : mix all buffers } else { const jack_int_t* connections = manager->GetConnections(port_index); void* buffers[CONNECTION_NUM_FOR_PORT]; jack_port_id_t src_index; int i; for (i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((src_index = connections[i]) != EMPTY); i++) { AssertPort(src_index); buffers[i] = GetBuffer(src_index, buffer_size); } port->MixBuffers(buffers, i, buffer_size); return port->GetBuffer(); } } // Server int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // Client { AssertPort(port_index); JackPort* port = GetPort(port_index); /** jackd.h * If @ref JackPortCanMonitor is set for this @a port, turn input * monitoring on or off. Otherwise, do nothing. if (!(fFlags & JackPortCanMonitor)) return -1; */ port->RequestMonitor(onoff); const jack_int_t* connections = ReadCurrentState()->GetConnections(port_index); if ((port->fFlags & JackPortIsOutput) == 0) { // ?? Taken from jack, why not (port->fFlags & JackPortIsInput) ? jack_port_id_t src_index; for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((src_index = connections[i]) != EMPTY); i++) { // XXX much worse things will happen if there is a feedback loop !!! RequestMonitor(src_index, onoff); } } return 0; } // Client jack_nframes_t JackGraphManager::ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count) { const jack_int_t* connections = ReadCurrentState()->GetConnections(port_index); jack_nframes_t max_latency = 0; jack_port_id_t dst_index; if (hop_count > 8) return GetPort(port_index)->GetLatency(); for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((dst_index = connections[i]) != EMPTY); i++) { if (src_port_index != dst_index) { AssertPort(dst_index); JackPort* dst_port = GetPort(dst_index); jack_nframes_t this_latency = (dst_port->fFlags & JackPortIsTerminal) ? dst_port->GetLatency() : ComputeTotalLatencyAux(dst_index, port_index, manager, hop_count + 1); max_latency = ((max_latency > this_latency) ? max_latency : this_latency); } } return max_latency + GetPort(port_index)->GetLatency(); } // Client int JackGraphManager::ComputeTotalLatency(jack_port_id_t port_index) { UInt16 cur_index; UInt16 next_index; JackPort* port = GetPort(port_index); AssertPort(port_index); do { cur_index = GetCurrentIndex(); port->fTotalLatency = ComputeTotalLatencyAux(port_index, port_index, ReadCurrentState(), 0); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read jack_log("JackGraphManager::GetTotalLatency port_index = %ld total latency = %ld", port_index, port->fTotalLatency); return 0; } // Client int JackGraphManager::ComputeTotalLatencies() { jack_port_id_t port_index; for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (port->IsUsed()) { ComputeTotalLatency(port_index); } } return 0; } void JackGraphManager::RecalculateLatencyAux(jack_port_id_t port_index, jack_latency_callback_mode_t mode) { const jack_int_t* connections = ReadCurrentState()->GetConnections(port_index); JackPort* port = GetPort(port_index); jack_latency_range_t latency = { UINT32_MAX, 0 }; jack_port_id_t dst_index; for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((dst_index = connections[i]) != EMPTY); i++) { AssertPort(dst_index); JackPort* dst_port = GetPort(dst_index); jack_latency_range_t other_latency; dst_port->GetLatencyRange(mode, &other_latency); if (other_latency.max > latency.max) { latency.max = other_latency.max; } if (other_latency.min < latency.min) { latency.min = other_latency.min; } } if (latency.min == UINT32_MAX) { latency.min = 0; } port->SetLatencyRange(mode, &latency); } void JackGraphManager::RecalculateLatency(jack_port_id_t port_index, jack_latency_callback_mode_t mode) { UInt16 cur_index; UInt16 next_index; do { cur_index = GetCurrentIndex(); RecalculateLatencyAux(port_index, mode); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read //jack_log("JackGraphManager::RecalculateLatency port_index = %ld", port_index); } // Server void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) { jack_log("JackGraphManager::SetBufferSize size = %ld", buffer_size); jack_port_id_t port_index; for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (port->IsUsed()) { port->ClearBuffer(buffer_size); } } } // Server jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) { jack_port_id_t port_index; // Available ports start at FIRST_AVAILABLE_PORT (= 1), otherwise a port_index of 0 is "seen" as a NULL port by the external API... for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (!port->IsUsed()) { jack_log("JackGraphManager::AllocatePortAux port_index = %ld name = %s type = %s", port_index, port_name, port_type); if (!port->Allocate(refnum, port_name, port_type, flags)) { return NO_PORT; } break; } } return (port_index < fPortMax) ? port_index : NO_PORT; } // Server jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, const char* port_type, JackPortFlags flags, jack_nframes_t buffer_size) { JackConnectionManager* manager = WriteNextStateStart(); jack_port_id_t port_index = AllocatePortAux(refnum, port_name, port_type, flags); if (port_index != NO_PORT) { JackPort* port = GetPort(port_index); assert(port); port->ClearBuffer(buffer_size); int res; if (flags & JackPortIsOutput) { res = manager->AddOutputPort(refnum, port_index); } else { res = manager->AddInputPort(refnum, port_index); } // Insertion failure if (res < 0) { port->Release(); port_index = NO_PORT; } } WriteNextStateStop(); return port_index; } // Server int JackGraphManager::ReleasePort(int refnum, jack_port_id_t port_index) { JackConnectionManager* manager = WriteNextStateStart(); JackPort* port = GetPort(port_index); int res; if (port->fFlags & JackPortIsOutput) { DisconnectAllOutput(port_index); res = manager->RemoveOutputPort(refnum, port_index); } else { DisconnectAllInput(port_index); res = manager->RemoveInputPort(refnum, port_index); } port->Release(); WriteNextStateStop(); return res; } void JackGraphManager::GetInputPorts(int refnum, jack_int_t* res) { JackConnectionManager* manager = WriteNextStateStart(); const jack_int_t* input = manager->GetInputPorts(refnum); memcpy(res, input, sizeof(jack_int_t) * PORT_NUM_FOR_CLIENT); WriteNextStateStop(); } void JackGraphManager::GetOutputPorts(int refnum, jack_int_t* res) { JackConnectionManager* manager = WriteNextStateStart(); const jack_int_t* output = manager->GetOutputPorts(refnum); memcpy(res, output, sizeof(jack_int_t) * PORT_NUM_FOR_CLIENT); WriteNextStateStop(); } // Server void JackGraphManager::RemoveAllPorts(int refnum) { jack_log("JackGraphManager::RemoveAllPorts ref = %ld", refnum); JackConnectionManager* manager = WriteNextStateStart(); jack_port_id_t port_index; // Warning : ReleasePort shift port to left, thus we always remove the first port until the "input" table is empty const jack_int_t* input = manager->GetInputPorts(refnum); while ((port_index = input[0]) != EMPTY) { int res = ReleasePort(refnum, port_index); if (res < 0) { jack_error("JackGraphManager::RemoveAllPorts failure ref = %ld port_index = %ld", refnum, port_index); assert(true); break; } } // Warning : ReleasePort shift port to left, thus we always remove the first port until the "output" table is empty const jack_int_t* output = manager->GetOutputPorts(refnum); while ((port_index = output[0]) != EMPTY) { int res = ReleasePort(refnum, port_index); if (res < 0) { jack_error("JackGraphManager::RemoveAllPorts failure ref = %ld port_index = %ld", refnum, port_index); assert(true); break; } } WriteNextStateStop(); } // Server void JackGraphManager::DisconnectAllPorts(int refnum) { int i; jack_log("JackGraphManager::DisconnectAllPorts ref = %ld", refnum); JackConnectionManager* manager = WriteNextStateStart(); const jack_int_t* input = manager->GetInputPorts(refnum); for (i = 0; i < PORT_NUM_FOR_CLIENT && input[i] != EMPTY ; i++) { DisconnectAllInput(input[i]); } const jack_int_t* output = manager->GetOutputPorts(refnum); for (i = 0; i < PORT_NUM_FOR_CLIENT && output[i] != EMPTY; i++) { DisconnectAllOutput(output[i]); } WriteNextStateStop(); } // Server void JackGraphManager::DisconnectAllInput(jack_port_id_t port_index) { jack_log("JackGraphManager::DisconnectAllInput port_index = %ld", port_index); JackConnectionManager* manager = WriteNextStateStart(); for (unsigned int i = 0; i < fPortMax; i++) { if (manager->IsConnected(i, port_index)) { jack_log("JackGraphManager::Disconnect i = %ld port_index = %ld", i, port_index); Disconnect(i, port_index); } } WriteNextStateStop(); } // Server void JackGraphManager::DisconnectAllOutput(jack_port_id_t port_index) { jack_log("JackGraphManager::DisconnectAllOutput port_index = %ld ", port_index); JackConnectionManager* manager = WriteNextStateStart(); const jack_int_t* connections = manager->GetConnections(port_index); while (connections[0] != EMPTY) { Disconnect(port_index, connections[0]); // Warning : Disconnect shift port to left } WriteNextStateStop(); } // Server int JackGraphManager::DisconnectAll(jack_port_id_t port_index) { AssertPort(port_index); JackPort* port = GetPort(port_index); if (port->fFlags & JackPortIsOutput) { DisconnectAllOutput(port_index); } else { DisconnectAllInput(port_index); } return 0; } // Server void JackGraphManager::GetConnections(jack_port_id_t port_index, jack_int_t* res) { JackConnectionManager* manager = WriteNextStateStart(); const jack_int_t* connections = manager->GetConnections(port_index); memcpy(res, connections, sizeof(jack_int_t) * CONNECTION_NUM_FOR_PORT); WriteNextStateStop(); } // Server void JackGraphManager::Activate(int refnum) { DirectConnect(FREEWHEEL_DRIVER_REFNUM, refnum); DirectConnect(refnum, FREEWHEEL_DRIVER_REFNUM); } /* Disconnection from the FW must be done in last otherwise an intermediate "unconnected" (thus unactivated) state may happen where the client is still checked for its end. */ // Server void JackGraphManager::Deactivate(int refnum) { // Disconnect only when needed if (IsDirectConnection(refnum, FREEWHEEL_DRIVER_REFNUM)) { DirectDisconnect(refnum, FREEWHEEL_DRIVER_REFNUM); } else { jack_log("JackServer::Deactivate client = %ld was not activated", refnum); } // Disconnect only when needed if (IsDirectConnection(FREEWHEEL_DRIVER_REFNUM, refnum)) { DirectDisconnect(FREEWHEEL_DRIVER_REFNUM, refnum); } else { jack_log("JackServer::Deactivate client = %ld was not activated", refnum); } } // Server int JackGraphManager::GetInputRefNum(jack_port_id_t port_index) { AssertPort(port_index); JackConnectionManager* manager = WriteNextStateStart(); int res = manager->GetInputRefNum(port_index); WriteNextStateStop(); return res; } // Server int JackGraphManager::GetOutputRefNum(jack_port_id_t port_index) { AssertPort(port_index); JackConnectionManager* manager = WriteNextStateStart(); int res = manager->GetOutputRefNum(port_index); WriteNextStateStop(); return res; } int JackGraphManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst) { JackConnectionManager* manager = WriteNextStateStart(); jack_log("JackGraphManager::Connect port_src = %ld port_dst = %ld", port_src, port_dst); JackPort* src = GetPort(port_src); JackPort* dst = GetPort(port_dst); int res = 0; if (!src->fInUse || !dst->fInUse) { if (!src->fInUse) jack_error("JackGraphManager::Connect port_src = %ld not used name = %s", port_src, GetPort(port_src)->fName); if (!dst->fInUse) jack_error("JackGraphManager::Connect port_dst = %ld not used name = %s", port_dst, GetPort(port_dst)->fName); res = -1; goto end; } if (src->fTypeId != dst->fTypeId) { jack_error("JackGraphManager::Connect different port types port_src = %ld port_dst = %ld", port_src, port_dst); res = -1; goto end; } if (manager->IsConnected(port_src, port_dst)) { jack_error("JackGraphManager::Connect already connected port_src = %ld port_dst = %ld", port_src, port_dst); res = EEXIST; goto end; } res = manager->Connect(port_src, port_dst); if (res < 0) { jack_error("JackGraphManager::Connect failed port_src = %ld port_dst = %ld", port_src, port_dst); goto end; } res = manager->Connect(port_dst, port_src); if (res < 0) { jack_error("JackGraphManager::Connect failed port_dst = %ld port_src = %ld", port_dst, port_src); goto end; } if (manager->IsLoopPath(port_src, port_dst)) { jack_log("JackGraphManager::Connect: LOOP detected"); manager->IncFeedbackConnection(port_src, port_dst); } else { manager->IncDirectConnection(port_src, port_dst); } end: WriteNextStateStop(); return res; } // Server int JackGraphManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst) { JackConnectionManager* manager = WriteNextStateStart(); jack_log("JackGraphManager::Disconnect port_src = %ld port_dst = %ld", port_src, port_dst); bool in_use_src = GetPort(port_src)->fInUse; bool in_use_dst = GetPort(port_dst)->fInUse; int res = 0; if (!in_use_src || !in_use_dst) { if (!in_use_src) jack_error("JackGraphManager::Disconnect: port_src = %ld not used name = %s", port_src, GetPort(port_src)->fName); if (!in_use_dst) jack_error("JackGraphManager::Disconnect: port_src = %ld not used name = %s", port_dst, GetPort(port_dst)->fName); res = -1; goto end; } if (!manager->IsConnected(port_src, port_dst)) { jack_error("JackGraphManager::Disconnect not connected port_src = %ld port_dst = %ld", port_src, port_dst); res = -1; goto end; } res = manager->Disconnect(port_src, port_dst); if (res < 0) { jack_error("JackGraphManager::Disconnect failed port_src = %ld port_dst = %ld", port_src, port_dst); goto end; } res = manager->Disconnect(port_dst, port_src); if (res < 0) { jack_error("JackGraphManager::Disconnect failed port_dst = %ld port_src = %ld", port_dst, port_src); goto end; } if (manager->IsFeedbackConnection(port_src, port_dst)) { jack_log("JackGraphManager::Disconnect: FEEDBACK removed"); manager->DecFeedbackConnection(port_src, port_dst); } else { manager->DecDirectConnection(port_src, port_dst); } end: WriteNextStateStop(); return res; } // Client int JackGraphManager::IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) { JackConnectionManager* manager = ReadCurrentState(); return manager->IsConnected(port_src, port_dst); } // Server int JackGraphManager::CheckPorts(jack_port_id_t port_src, jack_port_id_t port_dst) { JackPort* src = GetPort(port_src); JackPort* dst = GetPort(port_dst); if ((dst->fFlags & JackPortIsInput) == 0) { jack_error("Destination port in attempted (dis)connection of %s and %s is not an input port", src->fName, dst->fName); return -1; } if ((src->fFlags & JackPortIsOutput) == 0) { jack_error("Source port in attempted (dis)connection of %s and %s is not an output port", src->fName, dst->fName); return -1; } return 0; } int JackGraphManager::GetTwoPorts(const char* src_name, const char* dst_name, jack_port_id_t* port_src, jack_port_id_t* port_dst) { jack_log("JackGraphManager::CheckConnect src_name = %s dst_name = %s", src_name, dst_name); if ((*port_src = GetPort(src_name)) == NO_PORT) { jack_error("Unknown source port in attempted (dis)connection src_name [%s] dst_name [%s]", src_name, dst_name); return -1; } if ((*port_dst = GetPort(dst_name)) == NO_PORT) { jack_error("Unknown destination port in attempted (dis)connection src_name [%s] dst_name [%s]", src_name, dst_name); return -1; } return 0; } // Client : port array jack_port_id_t JackGraphManager::GetPort(const char* name) { for (unsigned int i = 0; i < fPortMax; i++) { JackPort* port = GetPort(i); if (port->IsUsed() && port->NameEquals(name)) { return i; } } return NO_PORT; } /*! \brief Get the connection port name array. */ // Client void JackGraphManager::GetConnectionsAux(JackConnectionManager* manager, const char** res, jack_port_id_t port_index) { const jack_int_t* connections = manager->GetConnections(port_index); jack_int_t index; int i; // Cleanup connection array memset(res, 0, sizeof(char*) * CONNECTION_NUM_FOR_PORT); for (i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((index = connections[i]) != EMPTY); i++) { JackPort* port = GetPort(index); res[i] = port->fName; } res[i] = NULL; } /* Use the state returned by ReadCurrentState and check that the state was not changed during the read operation. The operation is lock-free since there is no intermediate state in the write operation that could cause the read to loop forever. */ // Client const char** JackGraphManager::GetConnections(jack_port_id_t port_index) { const char** res = (const char**)malloc(sizeof(char*) * CONNECTION_NUM_FOR_PORT); UInt16 cur_index, next_index; if (!res) return NULL; do { cur_index = GetCurrentIndex(); GetConnectionsAux(ReadCurrentState(), res, port_index); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read if (res[0]) { // At least one connection return res; } else { // Empty array, should return NULL free(res); return NULL; } } // Client void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags) { int match_cnt = 0; regex_t port_regex, type_regex; if (port_name_pattern && port_name_pattern[0]) { regcomp(&port_regex, port_name_pattern, REG_EXTENDED | REG_NOSUB); } if (type_name_pattern && type_name_pattern[0]) { regcomp(&type_regex, type_name_pattern, REG_EXTENDED | REG_NOSUB); } // Cleanup port array memset(matching_ports, 0, sizeof(char*) * fPortMax); for (unsigned int i = 0; i < fPortMax; i++) { bool matching = true; JackPort* port = GetPort(i); if (port->IsUsed()) { if (flags) { if ((port->fFlags & flags) != flags) { matching = false; } } if (matching && port_name_pattern && port_name_pattern[0]) { if (regexec(&port_regex, port->GetName(), 0, NULL, 0)) { matching = false; } } if (matching && type_name_pattern && type_name_pattern[0]) { if (regexec(&type_regex, port->GetType(), 0, NULL, 0)) { matching = false; } } if (matching) { matching_ports[match_cnt++] = port->fName; } } } matching_ports[match_cnt] = 0; if (port_name_pattern && port_name_pattern[0]) { regfree(&port_regex); } if (type_name_pattern && type_name_pattern[0]) { regfree(&type_regex); } } // Client /* Check that the state was not changed during the read operation. The operation is lock-free since there is no intermediate state in the write operation that could cause the read to loop forever. */ const char** JackGraphManager::GetPorts(const char* port_name_pattern, const char* type_name_pattern, unsigned long flags) { const char** res = (const char**)malloc(sizeof(char*) * fPortMax); UInt16 cur_index, next_index; if (!res) return NULL; do { cur_index = GetCurrentIndex(); GetPortsAux(res, port_name_pattern, type_name_pattern, flags); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read if (res[0]) { // At least one port return res; } else { free(res); // Empty array, should return NULL return NULL; } } // Server void JackGraphManager::Save(JackConnectionManager* dst) { JackConnectionManager* manager = WriteNextStateStart(); memcpy(dst, manager, sizeof(JackConnectionManager)); WriteNextStateStop(); } // Server void JackGraphManager::Restore(JackConnectionManager* src) { JackConnectionManager* manager = WriteNextStateStart(); memcpy(manager, src, sizeof(JackConnectionManager)); WriteNextStateStop(); } } // end of namespace 1.9.12~dfsg/common/JackAtomicState.h0000644000000000000000000001620113214314510016007 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAtomicState__ #define __JackAtomicState__ #include "JackAtomic.h" #include "JackCompilerDeps.h" #include // for memcpy namespace Jack { /*! \brief Counter for CAS */ PRE_PACKED_STRUCTURE struct AtomicCounter { union { struct { UInt16 fShortVal1; // Cur UInt16 fShortVal2; // Next } scounter; UInt32 fLongVal; }info; AtomicCounter() { info.fLongVal = 0; } AtomicCounter(volatile const AtomicCounter& obj) { info.fLongVal = obj.info.fLongVal; } AtomicCounter(volatile AtomicCounter& obj) { info.fLongVal = obj.info.fLongVal; } AtomicCounter& operator=(AtomicCounter& obj) { info.fLongVal = obj.info.fLongVal; return *this; } AtomicCounter& operator=(volatile AtomicCounter& obj) { info.fLongVal = obj.info.fLongVal; return *this; } } POST_PACKED_STRUCTURE; #define Counter(e) (e).info.fLongVal #define CurIndex(e) (e).info.scounter.fShortVal1 #define NextIndex(e) (e).info.scounter.fShortVal2 #define CurArrayIndex(e) (CurIndex(e) & 0x0001) #define NextArrayIndex(e) ((CurIndex(e) + 1) & 0x0001) /*! \brief A class to handle two states (switching from one to the other) in a lock-free manner */ // CHECK livelock PRE_PACKED_STRUCTURE template class JackAtomicState { protected: T fState[2]; volatile AtomicCounter fCounter; SInt32 fCallWriteCounter; UInt32 WriteNextStateStartAux() { AtomicCounter old_val; AtomicCounter new_val; UInt32 cur_index; UInt32 next_index; bool need_copy; do { old_val = fCounter; new_val = old_val; cur_index = CurArrayIndex(new_val); next_index = NextArrayIndex(new_val); need_copy = (CurIndex(new_val) == NextIndex(new_val)); NextIndex(new_val) = CurIndex(new_val); // Invalidate next index } while (!CAS(Counter(old_val), Counter(new_val), (UInt32*)&fCounter)); if (need_copy) memcpy(&fState[next_index], &fState[cur_index], sizeof(T)); return next_index; } void WriteNextStateStopAux() { AtomicCounter old_val; AtomicCounter new_val; do { old_val = fCounter; new_val = old_val; NextIndex(new_val)++; // Set next index } while (!CAS(Counter(old_val), Counter(new_val), (UInt32*)&fCounter)); } public: JackAtomicState() { Counter(fCounter) = 0; fCallWriteCounter = 0; } ~JackAtomicState() // Not virtual ?? {} /*! \brief Returns the current state : only valid in the RT reader thread */ T* ReadCurrentState() { return &fState[CurArrayIndex(fCounter)]; } /*! \brief Returns the current state index */ UInt16 GetCurrentIndex() { return CurIndex(fCounter); } /*! \brief Tries to switch to the next state and returns the new current state (either the same as before if case of switch failure or the new one) */ T* TrySwitchState() { AtomicCounter old_val; AtomicCounter new_val; do { old_val = fCounter; new_val = old_val; CurIndex(new_val) = NextIndex(new_val); // Prepare switch } while (!CAS(Counter(old_val), Counter(new_val), (UInt32*)&fCounter)); return &fState[CurArrayIndex(fCounter)]; // Read the counter again } /*! \brief Tries to switch to the next state and returns the new current state (either the same as before if case of switch failure or the new one) */ T* TrySwitchState(bool* result) { AtomicCounter old_val; AtomicCounter new_val; do { old_val = fCounter; new_val = old_val; *result = (CurIndex(new_val) != NextIndex(new_val)); CurIndex(new_val) = NextIndex(new_val); // Prepare switch } while (!CAS(Counter(old_val), Counter(new_val), (UInt32*)&fCounter)); return &fState[CurArrayIndex(fCounter)]; // Read the counter again } /*! \brief Start write operation : setup and returns the next state to update, check for recursive write calls. */ T* WriteNextStateStart() { UInt32 next_index = (fCallWriteCounter++ == 0) ? WriteNextStateStartAux() : NextArrayIndex(fCounter); // We are inside a wrapping WriteNextStateStart call, NextArrayIndex can be read safely return &fState[next_index]; } /*! \brief Stop write operation : make the next state ready to be used by the RT thread */ void WriteNextStateStop() { if (--fCallWriteCounter == 0) WriteNextStateStopAux(); } bool IsPendingChange() { return CurIndex(fCounter) != NextIndex(fCounter); } /* // Single writer : write methods get the *next* state to be updated void TestWriteMethod() { T* state = WriteNextStateStart(); ...... ...... WriteNextStateStop(); } // First RT call possibly switch state void TestReadRTMethod1() { T* state = TrySwitchState(); ...... ...... } // Other RT methods can safely use the current state during the *same* RT cycle void TestReadRTMethod2() { T* state = ReadCurrentState(); ...... ...... } // Non RT read methods : must check state coherency void TestReadMethod() { T* state; UInt16 cur_index; UInt16 next_index = GetCurrentIndex(); do { cur_index = next_index; state = ReadCurrentState(); ...... ...... next_index = GetCurrentIndex(); } while (cur_index != next_index); } */ } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackEngine.cpp0000644000000000000000000011306613214314510015341 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include "JackSystemDeps.h" #include "JackLockedEngine.h" #include "JackExternalClient.h" #include "JackInternalClient.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackServerGlobals.h" #include "JackGlobals.h" #include "JackChannel.h" #include "JackError.h" namespace Jack { JackEngine::JackEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* control, char self_connect_mode) : JackLockAble(control->fServerName), fSignal(control->fServerName) { fGraphManager = manager; fSynchroTable = table; fEngineControl = control; fSelfConnectMode = self_connect_mode; for (int i = 0; i < CLIENT_NUM; i++) { fClientTable[i] = NULL; } fLastSwitchUsecs = 0; fMaxUUID = 0; fSessionPendingReplies = 0; fSessionTransaction = NULL; fSessionResult = NULL; } JackEngine::~JackEngine() {} int JackEngine::Open() { jack_log("JackEngine::Open"); // Open audio thread => request thread communication channel if (fChannel.Open(fEngineControl->fServerName) < 0) { jack_error("Cannot connect to server"); return -1; } else { return 0; } } int JackEngine::Close() { jack_log("JackEngine::Close"); fChannel.Close(); // Close remaining clients (RT is stopped) for (int i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) { if (JackLoadableInternalClient* loadable_client = dynamic_cast(fClientTable[i])) { jack_log("JackEngine::Close loadable client = %s", loadable_client->GetClientControl()->fName); loadable_client->Close(); fClientTable[i] = NULL; delete loadable_client; } else if (JackExternalClient* external_client = dynamic_cast(fClientTable[i])) { jack_log("JackEngine::Close external client = %s", external_client->GetClientControl()->fName); external_client->Close(); fClientTable[i] = NULL; delete external_client; } } return 0; } void JackEngine::NotifyQuit() { fChannel.NotifyQuit(); } //----------------------------- // Client ressource management //----------------------------- int JackEngine::AllocateRefnum() { for (int i = 0; i < CLIENT_NUM; i++) { if (!fClientTable[i]) { jack_log("JackEngine::AllocateRefNum ref = %ld", i); return i; } } return -1; } void JackEngine::ReleaseRefnum(int refnum) { fClientTable[refnum] = NULL; if (fEngineControl->fTemporary) { int i; for (i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) { if (fClientTable[i]) { break; } } if (i == CLIENT_NUM) { // Last client and temporay case: quit the server jack_log("JackEngine::ReleaseRefnum server quit"); fEngineControl->fTemporary = false; throw JackTemporaryException(); } } } //------------------ // Graph management //------------------ void JackEngine::ProcessNext(jack_time_t cur_cycle_begin) { fLastSwitchUsecs = cur_cycle_begin; if (fGraphManager->RunNextGraph()) { // True if the graph actually switched to a new state fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0); } fSignal.Signal(); // Signal for threads waiting for next cycle } void JackEngine::ProcessCurrent(jack_time_t cur_cycle_begin) { if (cur_cycle_begin < fLastSwitchUsecs + 2 * fEngineControl->fPeriodUsecs) { // Signal XRun only for the first failing cycle CheckXRun(cur_cycle_begin); } fGraphManager->RunCurrentGraph(); } bool JackEngine::Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { bool res = true; // Cycle begin fEngineControl->CycleBegin(fClientTable, fGraphManager, cur_cycle_begin, prev_cycle_end); // Graph if (fGraphManager->IsFinishedGraph()) { ProcessNext(cur_cycle_begin); res = true; } else { jack_log("Process: graph not finished!"); if (cur_cycle_begin > fLastSwitchUsecs + fEngineControl->fTimeOutUsecs) { jack_log("Process: switch to next state delta = %ld", long(cur_cycle_begin - fLastSwitchUsecs)); ProcessNext(cur_cycle_begin); res = true; } else { jack_log("Process: waiting to switch delta = %ld", long(cur_cycle_begin - fLastSwitchUsecs)); ProcessCurrent(cur_cycle_begin); res = false; } } // Cycle end fEngineControl->CycleEnd(fClientTable); return res; } /* Client that finish *after* the callback date are considered late even if their output buffers may have been correctly mixed in the time window: callbackUsecs <==> Read <==> Write. */ static const char* State2String(jack_client_state_t state) { switch (state) { case NotTriggered: return "NotTriggered"; case Triggered: return "Triggered"; case Running: return "Running"; case Finished: return "Finished"; default: return ""; } } void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions de fin { for (int i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && client->GetClientControl()->fActive) { JackClientTiming* timing = fGraphManager->GetClientTiming(i); jack_client_state_t status = timing->fStatus; jack_time_t finished_date = timing->fFinishedAt; if (status != NotTriggered && status != Finished) { jack_error("JackEngine::XRun: client = %s was not finished, state = %s", client->GetClientControl()->fName, State2String(status)); fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients } if (status == Finished && (long)(finished_date - callback_usecs) > 0) { jack_error("JackEngine::XRun: client %s finished after current callback", client->GetClientControl()->fName); fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients } } } } int JackEngine::ComputeTotalLatencies() { std::vector sorted; std::vector::iterator it; std::vector::reverse_iterator rit; fGraphManager->TopologicalSort(sorted); /* iterate over all clients in graph order, and emit * capture latency callback. */ for (it = sorted.begin(); it != sorted.end(); it++) { NotifyClient(*it, kLatencyCallback, true, "", 0, 0); } /* now issue playback latency callbacks in reverse graph order. */ for (rit = sorted.rbegin(); rit != sorted.rend(); rit++) { NotifyClient(*rit, kLatencyCallback, true, "", 1, 0); } return 0; } //--------------- // Notifications //--------------- int JackEngine::ClientNotify(JackClientInterface* client, int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { // Check if notification is needed if (!client->GetClientControl()->fCallback[notify]) { jack_log("JackEngine::ClientNotify: no callback for notification = %ld", notify); return 0; } int res1; // External client if (dynamic_cast(client)) { res1 = client->ClientNotify(refnum, name, notify, sync, message, value1, value2); // Important for internal client : unlock before calling the notification callbacks } else { bool res2 = Unlock(); res1 = client->ClientNotify(refnum, name, notify, sync, message, value1, value2); if (res2) { Lock(); } } if (res1 < 0) { jack_error("ClientNotify fails name = %s notification = %ld val1 = %ld val2 = %ld", name, notify, value1, value2); } return res1; } void JackEngine::NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2) { JackClientInterface* client = fClientTable[refnum]; if (client) { ClientNotify(client, refnum, client->GetClientControl()->fName, event, sync, message, value1, value2); } } void JackEngine::NotifyClients(int event, int sync, const char* message, int value1, int value2) { for (int i = 0; i < CLIENT_NUM; i++) { NotifyClient(i, event, sync, message, value1, value2); } } int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* new_name, int refnum) { jack_log("JackEngine::NotifyAddClient: name = %s", new_name); // Notify existing clients of the new client and new client of existing clients. for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* old_client = fClientTable[i]; if (old_client && old_client != new_client) { char* old_name = old_client->GetClientControl()->fName; if (ClientNotify(old_client, refnum, new_name, kAddClient, false, "", 0, 0) < 0) { jack_error("NotifyAddClient old_client fails name = %s", old_name); // Not considered as a failure... } if (ClientNotify(new_client, i, old_name, kAddClient, true, "", 0, 0) < 0) { jack_error("NotifyAddClient new_client fails name = %s", new_name); return -1; } } } return 0; } void JackEngine::NotifyRemoveClient(const char* name, int refnum) { // Notify existing clients (including the one beeing suppressed) of the removed client for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client) { ClientNotify(client, refnum, name, kRemoveClient, false, "", 0, 0); } } } // Coming from the driver void JackEngine::NotifyDriverXRun() { // Use the audio thread => request thread communication channel fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); } void JackEngine::NotifyClientXRun(int refnum) { if (refnum == ALL_CLIENTS) { NotifyClients(kXRunCallback, false, "", 0, 0); } else { NotifyClient(refnum, kXRunCallback, false, "", 0, 0); } } void JackEngine::NotifyGraphReorder() { ComputeTotalLatencies(); NotifyClients(kGraphOrderCallback, false, "", 0, 0); } void JackEngine::NotifyBufferSize(jack_nframes_t buffer_size) { NotifyClients(kBufferSizeCallback, true, "", buffer_size, 0); } void JackEngine::NotifySampleRate(jack_nframes_t sample_rate) { NotifyClients(kSampleRateCallback, true, "", sample_rate, 0); } void JackEngine::NotifyFailure(int code, const char* reason) { NotifyClients(kShutDownCallback, false, reason, code, 0); } void JackEngine::NotifyFreewheel(bool onoff) { if (onoff) { // Save RT state fEngineControl->fSavedRealTime = fEngineControl->fRealTime; fEngineControl->fRealTime = false; } else { // Restore RT state fEngineControl->fRealTime = fEngineControl->fSavedRealTime; fEngineControl->fSavedRealTime = false; } NotifyClients((onoff ? kStartFreewheelCallback : kStopFreewheelCallback), true, "", 0, 0); } void JackEngine::NotifyPortRegistation(jack_port_id_t port_index, bool onoff) { NotifyClients((onoff ? kPortRegistrationOnCallback : kPortRegistrationOffCallback), false, "", port_index, 0); } void JackEngine::NotifyPortRename(jack_port_id_t port, const char* old_name) { NotifyClients(kPortRenameCallback, false, old_name, port, 0); } void JackEngine::NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff) { NotifyClients((onoff ? kPortConnectCallback : kPortDisconnectCallback), false, "", src, dst); } void JackEngine::NotifyActivate(int refnum) { NotifyClient(refnum, kActivateClient, true, "", 0, 0); } //---------------------------- // Loadable client management //---------------------------- int JackEngine::GetInternalClientName(int refnum, char* name_res) { JackClientInterface* client = fClientTable[refnum]; assert(client); strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE); return 0; } int JackEngine::InternalClientHandle(const char* client_name, int* status, int* int_ref) { // Clear status *status = 0; for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && dynamic_cast(client) && (strcmp(client->GetClientControl()->fName, client_name) == 0)) { jack_log("InternalClientHandle found client name = %s ref = %ld", client_name, i); *int_ref = i; return 0; } } *status |= (JackNoSuchClient | JackFailure); return -1; } int JackEngine::InternalClientUnload(int refnum, int* status) { JackClientInterface* client = fClientTable[refnum]; if (client) { int res = client->Close(); delete client; *status = 0; return res; } else { *status = (JackNoSuchClient | JackFailure); return -1; } } //------------------- // Client management //------------------- int JackEngine::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status) { // Clear status *status = 0; strcpy(name_res, name); jack_log("Check protocol client = %ld server = %ld", protocol, JACK_PROTOCOL_VERSION); if (protocol != JACK_PROTOCOL_VERSION) { *status |= (JackFailure | JackVersionError); jack_error("JACK protocol mismatch (%d vs %d)", protocol, JACK_PROTOCOL_VERSION); return -1; } std::map::iterator res = fReservationMap.find(uuid); if (res != fReservationMap.end()) { strncpy(name_res, res->second.c_str(), JACK_CLIENT_NAME_SIZE); } else if (ClientCheckName(name)) { *status |= JackNameNotUnique; if (options & JackUseExactName) { jack_error("cannot create new client; %s already exists", name); *status |= JackFailure; return -1; } if (GenerateUniqueName(name_res)) { *status |= JackFailure; return -1; } } return 0; } bool JackEngine::GenerateUniqueName(char* name) { int tens, ones; int length = strlen(name); if (length > JACK_CLIENT_NAME_SIZE - 4) { jack_error("%s exists and is too long to make unique", name); return true; /* failure */ } /* generate a unique name by appending "-01".."-99" */ name[length++] = '-'; tens = length++; ones = length++; name[tens] = '0'; name[ones] = '1'; name[length] = '\0'; while (ClientCheckName(name)) { if (name[ones] == '9') { if (name[tens] == '9') { jack_error("client %s has 99 extra instances already", name); return true; /* give up */ } name[tens]++; name[ones] = '0'; } else { name[ones]++; } } return false; } bool JackEngine::ClientCheckName(const char* name) { for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && (strcmp(client->GetClientControl()->fName, name) == 0)) { return true; } } for (std::map::iterator i = fReservationMap.begin(); i != fReservationMap.end(); i++) { if (i->second == name) { return true; } } return false; } int JackEngine::GetNewUUID() { return fMaxUUID++; } void JackEngine::EnsureUUID(int uuid) { if (uuid > fMaxUUID) { fMaxUUID = uuid + 1; } for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && (client->GetClientControl()->fSessionID == uuid)) { client->GetClientControl()->fSessionID = GetNewUUID(); } } } int JackEngine::GetClientPID(const char* name) { for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && (strcmp(client->GetClientControl()->fName, name) == 0)) { return client->GetClientControl()->fPID; } } return 0; } int JackEngine::GetClientRefNum(const char* name) { for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && (strcmp(client->GetClientControl()->fName, name) == 0)) { return client->GetClientControl()->fRefNum; } } return -1; } // Used for external clients int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { char real_name[JACK_CLIENT_NAME_SIZE + 1]; if (uuid < 0) { uuid = GetNewUUID(); strncpy(real_name, name, JACK_CLIENT_NAME_SIZE); } else { std::map::iterator res = fReservationMap.find(uuid); if (res != fReservationMap.end()) { strncpy(real_name, res->second.c_str(), JACK_CLIENT_NAME_SIZE); fReservationMap.erase(uuid); } else { strncpy(real_name, name, JACK_CLIENT_NAME_SIZE); } EnsureUUID(uuid); } jack_log("JackEngine::ClientExternalOpen: uuid = %d, name = %s", uuid, real_name); int refnum = AllocateRefnum(); if (refnum < 0) { jack_error("No more refnum available"); return -1; } JackExternalClient* client = new JackExternalClient(); if (!fSynchroTable[refnum].Allocate(real_name, fEngineControl->fServerName, 0)) { jack_error("Cannot allocate synchro"); goto error; } if (client->Open(real_name, pid, refnum, uuid, shared_client) < 0) { jack_error("Cannot open client"); goto error; } if (!fSignal.LockedTimedWait(DRIVER_OPEN_TIMEOUT * 1000000)) { // Failure if RT thread is not running (problem with the driver...) jack_error("Driver is not running"); goto error; } fClientTable[refnum] = client; if (NotifyAddClient(client, real_name, refnum) < 0) { jack_error("Cannot notify add client"); goto error; } fGraphManager->InitRefNum(refnum); fEngineControl->ResetRollingUsecs(); *shared_engine = fEngineControl->GetShmIndex(); *shared_graph_manager = fGraphManager->GetShmIndex(); *ref = refnum; return 0; error: // Cleanup... fSynchroTable[refnum].Destroy(); fClientTable[refnum] = 0; client->Close(); delete client; return -1; } // Used for server driver clients int JackEngine::ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) { jack_log("JackEngine::ClientInternalOpen: name = %s", name); int refnum = AllocateRefnum(); if (refnum < 0) { jack_error("No more refnum available"); goto error; } if (!fSynchroTable[refnum].Allocate(name, fEngineControl->fServerName, 0)) { jack_error("Cannot allocate synchro"); goto error; } if (wait && !fSignal.LockedTimedWait(DRIVER_OPEN_TIMEOUT * 1000000)) { // Failure if RT thread is not running (problem with the driver...) jack_error("Driver is not running"); goto error; } fClientTable[refnum] = client; if (NotifyAddClient(client, name, refnum) < 0) { jack_error("Cannot notify add client"); goto error; } fGraphManager->InitRefNum(refnum); fEngineControl->ResetRollingUsecs(); *shared_engine = fEngineControl; *shared_manager = fGraphManager; *ref = refnum; return 0; error: // Cleanup... fSynchroTable[refnum].Destroy(); fClientTable[refnum] = 0; return -1; } // Used for external clients int JackEngine::ClientExternalClose(int refnum) { jack_log("JackEngine::ClientExternalClose ref = %ld", refnum); JackClientInterface* client = fClientTable[refnum]; assert(client); int res = ClientCloseAux(refnum, true); client->Close(); delete client; return res; } // Used for server internal clients or drivers when the RT thread is stopped int JackEngine::ClientInternalClose(int refnum, bool wait) { jack_log("JackEngine::ClientInternalClose ref = %ld", refnum); return ClientCloseAux(refnum, wait); } int JackEngine::ClientCloseAux(int refnum, bool wait) { jack_log("JackEngine::ClientCloseAux ref = %ld", refnum); JackClientInterface* client = fClientTable[refnum]; fEngineControl->fTransport.ResetTimebase(refnum); // Unregister all ports ==> notifications are sent jack_int_t ports[PORT_NUM_FOR_CLIENT]; int i; fGraphManager->GetInputPorts(refnum, ports); for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY); i++) { PortUnRegister(refnum, ports[i]); } fGraphManager->GetOutputPorts(refnum, ports); for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY); i++) { PortUnRegister(refnum, ports[i]); } // Remove the client from the table ReleaseRefnum(refnum); // Remove all ports fGraphManager->RemoveAllPorts(refnum); // Wait until next cycle to be sure client is not used anymore if (wait) { if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 2)) { // Must wait at least until a switch occurs in Process, even in case of graph end failure jack_error("JackEngine::ClientCloseAux wait error ref = %ld", refnum); } } // Notify running clients NotifyRemoveClient(client->GetClientControl()->fName, refnum); // Cleanup... fSynchroTable[refnum].Destroy(); fEngineControl->ResetRollingUsecs(); return 0; } int JackEngine::ClientActivate(int refnum, bool is_real_time) { JackClientInterface* client = fClientTable[refnum]; jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); if (is_real_time) { fGraphManager->Activate(refnum); } // Wait for graph state change to be effective if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { jack_error("JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); return -1; } else { jack_int_t input_ports[PORT_NUM_FOR_CLIENT]; jack_int_t output_ports[PORT_NUM_FOR_CLIENT]; fGraphManager->GetInputPorts(refnum, input_ports); fGraphManager->GetOutputPorts(refnum, output_ports); // Notify client NotifyActivate(refnum); // Then issue port registration notification for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { NotifyPortRegistation(input_ports[i], true); } for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { NotifyPortRegistation(output_ports[i], true); } return 0; } } // May be called without client int JackEngine::ClientDeactivate(int refnum) { JackClientInterface* client = fClientTable[refnum]; jack_log("JackEngine::ClientDeactivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); jack_int_t input_ports[PORT_NUM_FOR_CLIENT]; jack_int_t output_ports[PORT_NUM_FOR_CLIENT]; fGraphManager->GetInputPorts(refnum, input_ports); fGraphManager->GetOutputPorts(refnum, output_ports); // First disconnect all ports for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { PortDisconnect(-1, input_ports[i], ALL_PORTS); } for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { PortDisconnect(-1, output_ports[i], ALL_PORTS); } // Then issue port registration notification for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { NotifyPortRegistation(input_ports[i], false); } for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { NotifyPortRegistation(output_ports[i], false); } fGraphManager->Deactivate(refnum); fLastSwitchUsecs = 0; // Force switch to occur next cycle, even when called with "dead" clients // Wait for graph state change to be effective if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { jack_error("JackEngine::ClientDeactivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); return -1; } else { return 0; } } void JackEngine::ClientKill(int refnum) { jack_log("JackEngine::ClientKill ref = %ld", refnum); if (ClientDeactivate(refnum) < 0) { jack_error("JackEngine::ClientKill ref = %ld cannot be removed from the graph !!", refnum); } if (ClientExternalClose(refnum) < 0) { jack_error("JackEngine::ClientKill ref = %ld cannot be closed", refnum); } } //----------------- // Port management //----------------- int JackEngine::PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index) { jack_log("JackEngine::PortRegister ref = %ld name = %s type = %s flags = %d buffer_size = %d", refnum, name, type, flags, buffer_size); JackClientInterface* client = fClientTable[refnum]; // Check if port name already exists if (fGraphManager->GetPort(name) != NO_PORT) { jack_error("port_name \"%s\" already exists", name); return -1; } // buffer_size is actually ignored... *port_index = fGraphManager->AllocatePort(refnum, name, type, (JackPortFlags)flags, fEngineControl->fBufferSize); if (*port_index != NO_PORT) { if (client->GetClientControl()->fActive) { NotifyPortRegistation(*port_index, true); } return 0; } else { return -1; } } int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) { jack_log("JackEngine::PortUnRegister ref = %ld port_index = %ld", refnum, port_index); JackClientInterface* client = fClientTable[refnum]; assert(client); // Disconnect port ==> notification is sent PortDisconnect(-1, port_index, ALL_PORTS); if (fGraphManager->ReleasePort(refnum, port_index) == 0) { if (client->GetClientControl()->fActive) { NotifyPortRegistation(port_index, false); } return 0; } else { return -1; } } // this check is to prevent apps to self connect to other apps // TODO: make this work with multiple clients per app int JackEngine::CheckPortsConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { if (fSelfConnectMode == ' ') return 1; JackPort* src_port = fGraphManager->GetPort(src); JackPort* dst_port = fGraphManager->GetPort(dst); jack_log("JackEngine::CheckPortsConnect(ref = %d, src = %d, dst = %d)", refnum, src_port->GetRefNum(), dst_port->GetRefNum()); //jack_log("%s -> %s", src_port->GetName(), dst_port->GetName()); //jack_log("mode = '%c'", fSelfConnectMode); int src_self = src_port->GetRefNum() == refnum ? 1 : 0; int dst_self = dst_port->GetRefNum() == refnum ? 1 : 0; //jack_log("src_self is %s", src_self ? "true" : "false"); //jack_log("dst_self is %s", dst_self ? "true" : "false"); // 0 means client is connecting other client ports (control app patchbay functionality) // 1 means client is connecting its own port to port of other client (e.g. self connecting into "system" client) // 2 means client is connecting its own ports (for app internal functionality) int sum = src_self + dst_self; //jack_log("sum = %d", sum); if (sum == 0) return 1; char lmode = tolower(fSelfConnectMode); //jack_log("lmode = '%c'", lmode); if (sum == 2 && lmode == 'e') return 1; bool fail = lmode != fSelfConnectMode; // fail modes are upper case //jack_log("fail = %d", (int)fail); jack_info( "%s port self connect request%s (%s -> %s)", fail ? "rejecting" : "ignoring", sum == 1 ? " to external port" : "", src_port->GetName(), dst_port->GetName()); return fail ? -1 : 0; } int JackEngine::PortConnect(int refnum, const char* src, const char* dst) { jack_log("JackEngine::PortConnect ref = %d src = %s dst = %s", refnum, src, dst); jack_port_id_t port_src, port_dst; return (fGraphManager->GetTwoPorts(src, dst, &port_src, &port_dst) < 0) ? -1 : PortConnect(refnum, port_src, port_dst); } int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { jack_log("JackEngine::PortConnect ref = %d src = %d dst = %d", refnum, src, dst); JackClientInterface* client; int ref; if (fGraphManager->CheckPorts(src, dst) < 0) { return -1; } ref = fGraphManager->GetOutputRefNum(src); assert(ref >= 0); client = fClientTable[ref]; assert(client); if (!client->GetClientControl()->fActive) { jack_error("Cannot connect ports owned by inactive clients:" " \"%s\" is not active", client->GetClientControl()->fName); return -1; } ref = fGraphManager->GetInputRefNum(dst); assert(ref >= 0); client = fClientTable[ref]; assert(client); if (!client->GetClientControl()->fActive) { jack_error("Cannot connect ports owned by inactive clients:" " \"%s\" is not active", client->GetClientControl()->fName); return -1; } int res = CheckPortsConnect(refnum, src, dst); if (res != 1) { return res; } res = fGraphManager->Connect(src, dst); if (res == 0) { NotifyPortConnect(src, dst, true); } return res; } int JackEngine::PortDisconnect(int refnum, const char* src, const char* dst) { jack_log("JackEngine::PortDisconnect ref = %d src = %s dst = %s", refnum, src, dst); jack_port_id_t port_src, port_dst; return (fGraphManager->GetTwoPorts(src, dst, &port_src, &port_dst) < 0) ? -1 : PortDisconnect(refnum, port_src, port_dst); } int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { jack_log("JackEngine::PortDisconnect ref = %d src = %d dst = %d", refnum, src, dst); if (dst == ALL_PORTS) { jack_int_t connections[CONNECTION_NUM_FOR_PORT]; fGraphManager->GetConnections(src, connections); JackPort* port = fGraphManager->GetPort(src); int res = 0; if (port->GetFlags() & JackPortIsOutput) { for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && (connections[i] != EMPTY); i++) { if (PortDisconnect(refnum, src, connections[i]) != 0) { res = -1; } } } else { for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && (connections[i] != EMPTY); i++) { if (PortDisconnect(refnum, connections[i], src) != 0) { res = -1; } } } return res; } if (fGraphManager->CheckPorts(src, dst) < 0) { return -1; } int res = CheckPortsConnect(refnum, src, dst); if (res != 1) { return res; } res = fGraphManager->Disconnect(src, dst); if (res == 0) NotifyPortConnect(src, dst, false); return res; } int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) { char old_name[REAL_JACK_PORT_NAME_SIZE+1]; strcpy(old_name, fGraphManager->GetPort(port)->GetName()); fGraphManager->GetPort(port)->SetName(name); NotifyPortRename(port, old_name); return 0; } //-------------------- // Session management //-------------------- void JackEngine::SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, detail::JackChannelTransactionInterface *socket, JackSessionNotifyResult** result) { if (fSessionPendingReplies != 0) { JackSessionNotifyResult res(-1); res.Write(socket); jack_log("JackEngine::SessionNotify ... busy"); if (result != NULL) *result = NULL; return; } for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && (client->GetClientControl()->fSessionID < 0)) { client->GetClientControl()->fSessionID = GetNewUUID(); } } fSessionResult = new JackSessionNotifyResult(); for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && client->GetClientControl()->fCallback[kSessionCallback]) { // check if this is a notification to a specific client. if (target != NULL && strlen(target) != 0) { if (strcmp(target, client->GetClientControl()->fName)) { continue; } } char path_buf[JACK_PORT_NAME_SIZE]; if (path[strlen(path) - 1] == DIR_SEPARATOR) { snprintf(path_buf, sizeof path_buf, "%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR); } else { snprintf(path_buf, sizeof path_buf, "%s%c%s%c", path, DIR_SEPARATOR, client->GetClientControl()->fName, DIR_SEPARATOR); } int res = JackTools::MkDir(path_buf); if (res) jack_error("JackEngine::SessionNotify: can not create session directory '%s'", path_buf); int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path_buf, (int)type, 0); if (result == kPendingSessionReply) { fSessionPendingReplies += 1; } else if (result == kImmediateSessionReply) { char uuid_buf[JACK_UUID_SIZE]; snprintf(uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID); fSessionResult->fCommandList.push_back(JackSessionCommand(uuid_buf, client->GetClientControl()->fName, client->GetClientControl()->fSessionCommand, client->GetClientControl()->fSessionFlags)); } } } if (result != NULL) *result = fSessionResult; if (fSessionPendingReplies == 0) { fSessionResult->Write(socket); if (result == NULL) delete fSessionResult; fSessionResult = NULL; } else { fSessionTransaction = socket; } } int JackEngine::SessionReply(int refnum) { JackClientInterface* client = fClientTable[refnum]; assert(client); char uuid_buf[JACK_UUID_SIZE]; snprintf(uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID); fSessionResult->fCommandList.push_back(JackSessionCommand(uuid_buf, client->GetClientControl()->fName, client->GetClientControl()->fSessionCommand, client->GetClientControl()->fSessionFlags)); fSessionPendingReplies -= 1; if (fSessionPendingReplies == 0) { fSessionResult->Write(fSessionTransaction); if (fSessionTransaction != NULL) { delete fSessionResult; } fSessionResult = NULL; } return 0; } int JackEngine::GetUUIDForClientName(const char *client_name, char *uuid_res) { for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && (strcmp(client_name, client->GetClientControl()->fName) == 0)) { snprintf(uuid_res, JACK_UUID_SIZE, "%d", client->GetClientControl()->fSessionID); return 0; } } // Did not find name. return -1; } int JackEngine::GetClientNameForUUID(const char *uuid, char *name_res) { for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (!client) { continue; } char uuid_buf[JACK_UUID_SIZE]; snprintf(uuid_buf, JACK_UUID_SIZE, "%d", client->GetClientControl()->fSessionID); if (strcmp(uuid,uuid_buf) == 0) { strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE); return 0; } } // Did not find uuid. return -1; } int JackEngine::ReserveClientName(const char *name, const char *uuid) { jack_log("JackEngine::ReserveClientName ( name = %s, uuid = %s )", name, uuid); if (ClientCheckName(name)) { jack_log("name already taken"); return -1; } EnsureUUID(atoi(uuid)); fReservationMap[atoi(uuid)] = name; return 0; } int JackEngine::ClientHasSessionCallback(const char *name) { JackClientInterface* client = NULL; for (int i = 0; i < CLIENT_NUM; i++) { client = fClientTable[i]; if (client && (strcmp(client->GetClientControl()->fName, name) == 0)) { break; } } if (client) { return client->GetClientControl()->fCallback[kSessionCallback]; } else { return -1; } } } // end of namespace 1.9.12~dfsg/common/Jackdmp.cpp0000644000000000000000000005613313214314510014715 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2013 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include "types.h" #include "jack.h" #include "control.h" #include "JackConstants.h" #include "JackPlatformPlug.h" #ifdef __ANDROID__ #include "JackControlAPIAndroid.h" #endif #if defined(JACK_DBUS) && defined(__linux__) #include #include #include "audio_reserve.h" #endif /* This is a simple port of the old jackdmp.cpp file to use the new jack2 control API. Available options for the server are "hard-coded" in the source. A much better approach would be to use the control API to: - dynamically retrieve available server parameters and then prepare to parse them - get available drivers and their possible parameters, then prepare to parse them. */ #ifdef __APPLE__ #include #include static void notify_server_start(const char* server_name) { // Send notification to be used in the JackRouter plugin CFStringRef ref = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman); CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), CFSTR("com.grame.jackserver.start"), ref, NULL, kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); CFRelease(ref); } static void notify_server_stop(const char* server_name) { // Send notification to be used in the JackRouter plugin CFStringRef ref1 = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman); CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), CFSTR("com.grame.jackserver.stop"), ref1, NULL, kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); CFRelease(ref1); } #else static void notify_server_start(const char* server_name) {} static void notify_server_stop(const char* server_name) {} #endif static void copyright(FILE* file) { fprintf(file, "jackdmp " VERSION "\n" "Copyright 2001-2005 Paul Davis and others.\n" "Copyright 2004-2016 Grame.\n" "Copyright 2016-2017 Filipe Coelho.\n" "jackdmp comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; see the file COPYING for details\n"); } static jackctl_driver_t * jackctl_server_get_driver(jackctl_server_t *server, const char *driver_name) { const JSList * node_ptr = jackctl_server_get_drivers_list(server); while (node_ptr) { if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0) { return (jackctl_driver_t *)node_ptr->data; } node_ptr = jack_slist_next(node_ptr); } return NULL; } static jackctl_internal_t * jackctl_server_get_internal(jackctl_server_t *server, const char *internal_name) { const JSList * node_ptr = jackctl_server_get_internals_list(server); while (node_ptr) { if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0) { return (jackctl_internal_t *)node_ptr->data; } node_ptr = jack_slist_next(node_ptr); } return NULL; } static jackctl_parameter_t * jackctl_get_parameter(const JSList * parameters_list, const char * parameter_name) { while (parameters_list) { if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0) { return (jackctl_parameter_t *)parameters_list->data; } parameters_list = jack_slist_next(parameters_list); } return NULL; } #ifdef __ANDROID__ static void jackctl_server_switch_master_dummy(jackctl_server_t * server_ctl, char * master_driver_name) { static bool is_dummy_driver = false; if(!strcmp(master_driver_name, "dummy")) { return; } jackctl_driver_t * driver_ctr; if(is_dummy_driver) { is_dummy_driver = false; driver_ctr = jackctl_server_get_driver(server_ctl, master_driver_name); } else { is_dummy_driver = true; driver_ctr = jackctl_server_get_driver(server_ctl, "dummy"); } jackctl_server_switch_master(server_ctl, driver_ctr); } #endif static void print_server_drivers(jackctl_server_t *server, FILE* file) { const JSList * node_ptr = jackctl_server_get_drivers_list(server); fprintf(file, "Available backends:\n"); while (node_ptr) { jackctl_driver_t* driver = (jackctl_driver_t *)node_ptr->data; fprintf(file, " %s (%s)\n", jackctl_driver_get_name(driver), (jackctl_driver_get_type(driver) == JackMaster) ? "master" : "slave"); node_ptr = jack_slist_next(node_ptr); } fprintf(file, "\n"); } static void print_server_internals(jackctl_server_t *server, FILE* file) { const JSList * node_ptr = jackctl_server_get_internals_list(server); fprintf(file, "Available internals:\n"); while (node_ptr) { jackctl_internal_t* internal = (jackctl_internal_t *)node_ptr->data; fprintf(file, " %s\n", jackctl_internal_get_name(internal)); node_ptr = jack_slist_next(node_ptr); } fprintf(file, "\n"); } static void usage(FILE* file, jackctl_server_t *server, bool full = true) { jackctl_parameter_t * param; const JSList * server_parameters; uint32_t i; union jackctl_parameter_value value; fprintf(file, "\n" "Usage: jackdmp [ --no-realtime OR -r ]\n" " [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n" " (the two previous arguments are mutually exclusive. The default is --realtime)\n" " [ --name OR -n server-name ]\n" " [ --timeout OR -t client-timeout-in-msecs ]\n" " [ --loopback OR -L loopback-port-number ]\n" " [ --port-max OR -p maximum-number-of-ports]\n" " [ --slave-backend OR -X slave-backend-name ]\n" " [ --internal-client OR -I internal-client-name ]\n" " [ --internal-session-file OR -C internal-session-file ]\n" " [ --verbose OR -v ]\n" #ifdef __linux__ " [ --clocksource OR -c [ h(pet) | s(ystem) ]\n" #endif " [ --autoconnect OR -a ]\n"); server_parameters = jackctl_server_get_parameters(server); param = jackctl_get_parameter(server_parameters, "self-connect-mode"); fprintf(file, " where is one of:\n"); for (i = 0; i < jackctl_parameter_get_enum_constraints_count(param); i++) { value = jackctl_parameter_get_enum_constraint_value(param, i); fprintf(file, " '%c' - %s", value.c, jackctl_parameter_get_enum_constraint_description(param, i)); if (value.c == JACK_DEFAULT_SELF_CONNECT_MODE) { fprintf(file, " (default)"); } fprintf(file, "\n"); } fprintf(file, " [ --replace-registry ]\n" " [ --silent OR -s ]\n" " [ --sync OR -S ]\n" " [ --temporary OR -T ]\n" " [ --version OR -V ]\n" " -d master-backend-name [ ... master-backend args ... ]\n" " jackdmp -d master-backend-name --help\n" " to display options for each master backend\n\n"); if (full) { print_server_drivers(server, file); print_server_internals(server, file); } } // Prototype to be found in libjackserver extern "C" void silent_jack_error_callback(const char *desc); void print_version() { printf( "jackdmp version " VERSION " tmpdir " jack_server_dir " protocol %d" "\n", JACK_PROTOCOL_VERSION); exit(-1); } int main(int argc, char** argv) { jackctl_server_t * server_ctl; const JSList * server_parameters; const char* server_name = JACK_DEFAULT_SERVER_NAME; jackctl_driver_t * master_driver_ctl; jackctl_driver_t * loopback_driver_ctl = NULL; int replace_registry = 0; for(int a = 1; a < argc; ++a) { if( !strcmp(argv[a], "--version") || !strcmp(argv[a], "-V") ) { print_version(); } } const char *options = "-d:X:I:P:uvshrRL:STFl:t:mn:p:C:" "a:" #ifdef __linux__ "c:" #endif ; struct option long_options[] = { #ifdef __linux__ { "clock-source", 1, 0, 'c' }, #endif { "internal-session-file", 1, 0, 'C' }, { "loopback-driver", 1, 0, 'L' }, { "audio-driver", 1, 0, 'd' }, { "midi-driver", 1, 0, 'X' }, { "internal-client", 1, 0, 'I' }, { "verbose", 0, 0, 'v' }, { "help", 0, 0, 'h' }, { "port-max", 1, 0, 'p' }, { "no-mlock", 0, 0, 'm' }, { "name", 1, 0, 'n' }, { "unlock", 0, 0, 'u' }, { "realtime", 0, 0, 'R' }, { "no-realtime", 0, 0, 'r' }, { "replace-registry", 0, &replace_registry, 0 }, { "loopback", 0, 0, 'L' }, { "realtime-priority", 1, 0, 'P' }, { "timeout", 1, 0, 't' }, { "temporary", 0, 0, 'T' }, { "silent", 0, 0, 's' }, { "sync", 0, 0, 'S' }, { "autoconnect", 1, 0, 'a' }, { 0, 0, 0, 0 } }; int i,opt = 0; int option_index = 0; char* internal_session_file = NULL; char* master_driver_name = NULL; char** master_driver_args = NULL; int master_driver_nargs = 1; int loopback = 0; jackctl_sigmask_t * sigmask; jackctl_parameter_t* param; union jackctl_parameter_value value; std::list internals_list; std::list slaves_list; std::list::iterator it; // Assume that we fail. int return_value = -1; bool notify_sent = false; copyright(stdout); #if defined(JACK_DBUS) && defined(__linux__) if (getenv("JACK_NO_AUDIO_RESERVATION")) server_ctl = jackctl_server_create(NULL, NULL); else server_ctl = jackctl_server_create(audio_acquire, audio_release); #else server_ctl = jackctl_server_create(NULL, NULL); #endif if (server_ctl == NULL) { fprintf(stderr, "Failed to create server object\n"); return -1; } server_parameters = jackctl_server_get_parameters(server_ctl); opterr = 0; while (!master_driver_name && (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { #ifdef __linux__ case 'c': param = jackctl_get_parameter(server_parameters, "clock-source"); if (param != NULL) { if (tolower (optarg[0]) == 'h') { value.ui = JACK_TIMER_HPET; jackctl_parameter_set_value(param, &value); } else if (tolower (optarg[0]) == 'c') { /* For backwards compatibility with scripts, allow * the user to request the cycle clock on the * command line, but use the system clock instead */ value.ui = JACK_TIMER_SYSTEM_CLOCK; jackctl_parameter_set_value(param, &value); } else if (tolower (optarg[0]) == 's') { value.ui = JACK_TIMER_SYSTEM_CLOCK; jackctl_parameter_set_value(param, &value); } else { usage(stdout, server_ctl); goto destroy_server; } } break; #endif case 'a': param = jackctl_get_parameter(server_parameters, "self-connect-mode"); if (param != NULL) { bool value_valid = false; for (uint32_t k=0; k 0) { loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback"); if (loopback_driver_ctl != NULL) { const JSList * loopback_parameters = jackctl_driver_get_parameters(loopback_driver_ctl); param = jackctl_get_parameter(loopback_parameters, "channels"); if (param != NULL) { value.ui = loopback; jackctl_parameter_set_value(param, &value); } if (!jackctl_server_add_slave(server_ctl, loopback_driver_ctl)) { fprintf(stderr, "Driver \"loopback\" cannot be loaded\n"); goto close_server; } } else { fprintf(stderr, "Driver \"loopback\" not found\n"); goto close_server; } } // Start the server if (!jackctl_server_start(server_ctl)) { fprintf(stderr, "Failed to start server\n"); goto close_server; } // Internal clients for (it = internals_list.begin(); it != internals_list.end(); it++) { jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); if (internal_driver_ctl == NULL) { fprintf(stderr, "Unknown internal \"%s\"\n", *it); goto stop_server; } if (!jackctl_server_load_internal(server_ctl, internal_driver_ctl)) { fprintf(stderr, "Internal client \"%s\" cannot be loaded\n", *it); goto stop_server; } } if (internal_session_file != NULL) { if (!jackctl_server_load_session_file(server_ctl, internal_session_file)) { fprintf(stderr, "Internal session file %s cannot be loaded!\n", internal_session_file); goto stop_server; } } notify_server_start(server_name); notify_sent = true; return_value = 0; // Waits for signal #ifdef __ANDROID__ //reserve SIGUSR2 signal for switching master driver while(1) { int signal = jackctl_wait_signals_and_return(sigmask); if (signal == SIGUSR2) { jackctl_server_switch_master_dummy(server_ctl, master_driver_name); } else { break; } } #else jackctl_wait_signals(sigmask); #endif stop_server: if (!jackctl_server_stop(server_ctl)) { fprintf(stderr, "Cannot stop server...\n"); } close_server: if (loopback > 0 && loopback_driver_ctl) { jackctl_server_remove_slave(server_ctl, loopback_driver_ctl); } // Slave drivers for (it = slaves_list.begin(); it != slaves_list.end(); it++) { jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it); if (slave_driver_ctl) { jackctl_server_remove_slave(server_ctl, slave_driver_ctl); } } // Internal clients for (it = internals_list.begin(); it != internals_list.end(); it++) { jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); if (internal_driver_ctl) { jackctl_server_unload_internal(server_ctl, internal_driver_ctl); } } jackctl_server_close(server_ctl); destroy_server: jackctl_server_destroy(server_ctl); if (notify_sent) { notify_server_stop(server_name); } return return_value; } 1.9.12~dfsg/common/shm.h0000644000000000000000000001511613214314510013574 0ustar rootroot/* This module provides a set of abstract shared memory interfaces * with support using both System V and POSIX shared memory * implementations. The code is divided into three sections: * * - common (interface-independent) code * - POSIX implementation * - System V implementation * - Windows implementation * * The implementation used is determined by whether USE_POSIX_SHM was * set in the ./configure step. */ /* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2005-2012 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_shm_h__ #define __jack_shm_h__ #include #include #include "types.h" #include "JackCompilerDeps.h" #include "JackConstants.h" #define TRUE 1 #define FALSE 0 #ifdef __cplusplus extern "C" { #endif #define MAX_SERVERS 8 /* maximum concurrent servers */ #define MAX_SHM_ID 256 /* generally about 16 per server */ #define JACK_SHM_MAGIC 0x4a41434b /* shm magic number: "JACK" */ #define JACK_SHM_NULL_INDEX -1 /* NULL SHM index */ #define JACK_SHM_REGISTRY_INDEX -2 /* pseudo SHM index for registry */ /* On Mac OS X, SHM_NAME_MAX is the maximum length of a shared memory * segment name (instead of NAME_MAX or PATH_MAX as defined by the * standard). */ #ifdef USE_POSIX_SHM #ifndef NAME_MAX #define NAME_MAX 255 #endif #ifndef SHM_NAME_MAX #define SHM_NAME_MAX NAME_MAX #endif typedef char shm_name_t[SHM_NAME_MAX]; typedef shm_name_t jack_shm_id_t; #elif WIN32 #define NAME_MAX 255 #ifndef SHM_NAME_MAX #define SHM_NAME_MAX NAME_MAX #endif typedef char shm_name_t[SHM_NAME_MAX]; typedef shm_name_t jack_shm_id_t; #elif __ANDROID__ #ifndef NAME_MAX #define NAME_MAX 255 #endif #ifndef SHM_NAME_MAX #define SHM_NAME_MAX NAME_MAX #endif typedef char shm_name_t[SHM_NAME_MAX]; typedef shm_name_t jack_shm_id_t; typedef int jack_shm_fd_t; #else /* System V SHM */ typedef int jack_shm_id_t; #endif /* SHM type */ /* shared memory type */ typedef enum { shm_POSIX = 1, /* POSIX shared memory */ shm_SYSV = 2, /* System V shared memory */ shm_WIN32 = 3, /* Windows 32 shared memory */ shm_ANDROID = 4 /* Android shared memory */ } jack_shmtype_t; typedef int16_t jack_shm_registry_index_t; /** * A structure holding information about shared memory allocated by * JACK. this persists across invocations of JACK, and can be used by * multiple JACK servers. It contains no pointers and is valid across * address spaces. * * The registry consists of two parts: a header including an array of * server names, followed by an array of segment registry entries. */ typedef struct _jack_shm_server { #ifdef WIN32 int pid; /* process ID */ #else pid_t pid; /* process ID */ #endif char name[JACK_SERVER_NAME_SIZE+1]; } jack_shm_server_t; typedef struct _jack_shm_header { uint32_t magic; /* magic number */ uint16_t protocol; /* JACK protocol version */ jack_shmtype_t type; /* shm type */ jack_shmsize_t size; /* total registry segment size */ jack_shmsize_t hdr_len; /* size of header */ jack_shmsize_t entry_len; /* size of registry entry */ jack_shm_server_t server[MAX_SERVERS]; /* current server array */ } jack_shm_header_t; typedef struct _jack_shm_registry { jack_shm_registry_index_t index; /* offset into the registry */ #ifdef WIN32 int allocator; /* PID that created shm segment */ #else pid_t allocator; /* PID that created shm segment */ #endif jack_shmsize_t size; /* for POSIX unattach */ jack_shm_id_t id; /* API specific, see above */ #ifdef __ANDROID__ jack_shm_fd_t fd; #endif } jack_shm_registry_t; #define JACK_SHM_REGISTRY_SIZE (sizeof (jack_shm_header_t) \ + sizeof (jack_shm_registry_t) * MAX_SHM_ID) /** * a structure holding information about shared memory * allocated by JACK. this version is valid only * for a given address space. It contains a pointer * indicating where the shared memory has been * attached to the address space. */ PRE_PACKED_STRUCTURE struct _jack_shm_info { jack_shm_registry_index_t index; /* offset into the registry */ uint32_t size; #ifdef __ANDROID__ jack_shm_fd_t fd; #endif union { void *attached_at; /* address where attached */ char ptr_size[8]; } ptr; /* a "pointer" that has the same 8 bytes size when compling in 32 or 64 bits */ } POST_PACKED_STRUCTURE; typedef struct _jack_shm_info jack_shm_info_t; /* utility functions used only within JACK */ void jack_shm_copy_from_registry (jack_shm_info_t*, jack_shm_registry_index_t); void jack_shm_copy_to_registry (jack_shm_info_t*, jack_shm_registry_index_t*); int jack_release_shm_info (jack_shm_registry_index_t); char* jack_shm_addr (jack_shm_info_t* si); // here begin the API int jack_register_server (const char *server_name, int new_registry); int jack_unregister_server (const char *server_name); int jack_initialize_shm (const char *server_name); int jack_initialize_shm_server (void); int jack_initialize_shm_client (void); int jack_cleanup_shm (void); int jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result); void jack_release_shm (jack_shm_info_t*); void jack_release_lib_shm (jack_shm_info_t*); void jack_destroy_shm (jack_shm_info_t*); int jack_attach_shm (jack_shm_info_t*); int jack_attach_lib_shm (jack_shm_info_t*); int jack_attach_shm_read (jack_shm_info_t*); int jack_attach_lib_shm_read (jack_shm_info_t*); int jack_resize_shm (jack_shm_info_t*, jack_shmsize_t size); #ifdef __cplusplus } #endif #endif /* __jack_shm_h__ */ 1.9.12~dfsg/common/netjack.h0000644000000000000000000001223313214314510014421 0ustar rootroot /* Copyright (C) 2003 Robert Ham Copyright (C) 2005 Torben Hohn This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __NETJACK_H__ #define __NETJACK_H__ #include #include #include #include #include "jack/jslist.h" #if HAVE_CELT #include #endif #if HAVE_OPUS #include #include #endif #ifdef __cplusplus extern "C" { #endif struct _packet_cache; typedef struct _netjack_driver_state netjack_driver_state_t; struct _netjack_driver_state { jack_nframes_t net_period_up; jack_nframes_t net_period_down; jack_nframes_t sample_rate; jack_nframes_t bitdepth; jack_nframes_t period_size; jack_time_t period_usecs; int dont_htonl_floats; int always_deadline; jack_nframes_t codec_latency; unsigned int listen_port; unsigned int capture_channels; unsigned int playback_channels; unsigned int capture_channels_audio; unsigned int playback_channels_audio; unsigned int capture_channels_midi; unsigned int playback_channels_midi; JSList *capture_ports; JSList *playback_ports; JSList *playback_srcs; JSList *capture_srcs; jack_client_t *client; #ifdef WIN32 SOCKET sockfd; SOCKET outsockfd; #else int sockfd; int outsockfd; #endif struct sockaddr_in syncsource_address; int reply_port; int srcaddress_valid; int sync_state; unsigned int handle_transport_sync; unsigned int *rx_buf; unsigned int rx_bufsize; //unsigned int tx_bufsize; unsigned int mtu; unsigned int latency; unsigned int redundancy; jack_nframes_t expected_framecnt; int expected_framecnt_valid; unsigned int num_lost_packets; jack_time_t next_deadline; jack_time_t deadline_offset; int next_deadline_valid; int packet_data_valid; int resync_threshold; int running_free; int deadline_goodness; jack_time_t time_to_deadline; unsigned int use_autoconfig; unsigned int resample_factor; unsigned int resample_factor_up; int jitter_val; struct _packet_cache * packcache; #if HAVE_CELT CELTMode *celt_mode; #endif #if HAVE_OPUS OpusCustomMode* opus_mode; #endif }; int netjack_wait( netjack_driver_state_t *netj ); void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ); void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ; void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate ); void netjack_attach( netjack_driver_state_t *netj ); void netjack_detach( netjack_driver_state_t *netj ); netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, jack_client_t * client, const char *name, unsigned int capture_ports, unsigned int playback_ports, unsigned int capture_ports_midi, unsigned int playback_ports_midi, jack_nframes_t sample_rate, jack_nframes_t period_size, unsigned int listen_port, unsigned int transport_sync, unsigned int resample_factor, unsigned int resample_factor_up, unsigned int bitdepth, unsigned int use_autoconfig, unsigned int latency, unsigned int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ); void netjack_release( netjack_driver_state_t *netj ); int netjack_startup( netjack_driver_state_t *netj ); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/common/JackMidiPort.h0000644000000000000000000000566013214314510015330 0ustar rootroot/* Copyright (C) 2007 Dmitry Baikov Original JACK MIDI API implementation Copyright (C) 2004 Ian Esten This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiPort__ #define __JackMidiPort__ #include "types.h" #include "JackConstants.h" #include "JackPlatformPlug.h" #include /** Type for raw event data contained in @ref jack_midi_event_t. */ typedef unsigned char jack_midi_data_t; /** A Jack MIDI event. */ struct jack_midi_event_t { jack_nframes_t time; /**< Sample index at which event is valid */ size_t size; /**< Number of bytes of data in \a buffer */ jack_midi_data_t *buffer; /**< Raw MIDI data */ }; /** A Jack MIDI port type. */ #define JACK_DEFAULT_MIDI_TYPE "8 bit raw midi" namespace Jack { struct SERVER_EXPORT JackMidiEvent { // Most MIDI events are < 4 bytes in size, so we can save a lot, storing them inplace. enum { INLINE_SIZE_MAX = sizeof(jack_shmsize_t) }; uint32_t time; jack_shmsize_t size; union { jack_shmsize_t offset; jack_midi_data_t data[INLINE_SIZE_MAX]; }; jack_midi_data_t* GetData(void* buffer) { if (size <= INLINE_SIZE_MAX) { return data; } else { return (jack_midi_data_t*)buffer + offset; } } }; /* * To store events with arbitrarily sized payload, but still have O(1) indexed access * we use a trick here: * Events are stored in an linear array from the beginning of the buffer, * but their data (if not inlined) is stored from the end of the same buffer. */ struct SERVER_EXPORT JackMidiBuffer { enum { MAGIC = 0x900df00d }; uint32_t magic; jack_shmsize_t buffer_size; jack_nframes_t nframes; jack_shmsize_t write_pos; //!< data write position from the end of the buffer. uint32_t event_count; uint32_t lost_events; JackMidiEvent events[1]; // Using 0 size does not compile with older GCC versions, so use 1 here. int IsValid() const { return magic == MAGIC; } void Reset(jack_nframes_t nframes); jack_shmsize_t MaxEventSize() const; // checks only size constraints. jack_midi_data_t* ReserveEvent(jack_nframes_t time, jack_shmsize_t size); }; void MidiBufferInit(void* buffer, size_t buffer_size, jack_nframes_t nframes); } // namespace Jack #endif 1.9.12~dfsg/common/JackInternalClientChannel.h0000644000000000000000000001442613214314510020005 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackInternalClientChannel__ #define __JackInternalClientChannel__ #include "JackChannel.h" namespace Jack { /*! \brief JackClientChannel for server internal clients. */ class JackInternalClientChannel : public detail::JackClientChannelInterface { private: JackServer* fServer; JackLockedEngine* fEngine; public: JackInternalClientChannel(JackServer* server): fServer(server), fEngine(server->GetEngine()) {} virtual ~JackInternalClientChannel() {} void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open) { *result = fEngine->ClientCheck(name, uuid, name_res, protocol, options, status); } void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) { *result = fEngine->ClientInternalOpen(name, ref, shared_engine, shared_manager, client, true); } void ClientClose(int refnum, int* result) { *result = fEngine->ClientInternalClose(refnum, true); } void ClientActivate(int refnum, int is_real_time, int* result) { *result = fEngine->ClientActivate(refnum, is_real_time); } void ClientDeactivate(int refnum, int* result) { *result = fEngine->ClientDeactivate(refnum); } void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, unsigned int* port_index, int* result) { *result = fEngine->PortRegister(refnum, name, type, flags, buffer_size, port_index); } void PortUnRegister(int refnum, jack_port_id_t port_index, int* result) { *result = fEngine->PortUnRegister(refnum, port_index); } void PortConnect(int refnum, const char* src, const char* dst, int* result) { *result = fEngine->PortConnect(refnum, src, dst); } void PortDisconnect(int refnum, const char* src, const char* dst, int* result) { *result = fEngine->PortDisconnect(refnum, src, dst); } void PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) { *result = fEngine->PortConnect(refnum, src, dst); } void PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) { *result = fEngine->PortDisconnect(refnum, src, dst); } void PortRename(int refnum, jack_port_id_t port, const char* name, int* result) { *result = fEngine->PortRename(refnum, port, name); } void SetBufferSize(jack_nframes_t buffer_size, int* result) { *result = fServer->SetBufferSize(buffer_size); } void SetFreewheel(int onoff, int* result) { *result = fServer->SetFreewheel(onoff); } void ComputeTotalLatencies(int* result) { *result = fEngine->ComputeTotalLatencies(); } void ReleaseTimebase(int refnum, int* result) { *result = fServer->ReleaseTimebase(refnum); } void SetTimebaseCallback(int refnum, int conditional, int* result) { *result = fServer->SetTimebaseCallback(refnum, conditional); } void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) { *result = fEngine->GetInternalClientName(int_ref, name_res); } void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result) { *result = fEngine->InternalClientHandle(client_name, status, int_ref); } void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) { *result = fServer->InternalClientLoad1(client_name, so_name, objet_data, options, int_ref, uuid, status); } void InternalClientUnload(int refnum, int int_ref, int* status, int* result) { *result = fEngine->InternalClientUnload(int_ref, status); } void SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, jack_session_command_t** result) { JackSessionNotifyResult* res; fEngine->SessionNotify(refnum, target, type, path, NULL, &res); if (res == NULL) { *result = NULL; return; } *result = res->GetCommands(); delete(res); } void SessionReply(int refnum, int* result) { *result = fEngine->SessionReply(refnum); } void GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result) { *result = fEngine->GetUUIDForClientName(client_name, uuid_res); } void GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result) { *result = fEngine->GetClientNameForUUID(uuid, name_res); } void ReserveClientName(int refnum, const char* client_name, const char *uuid, int* result) { *result = fEngine->ReserveClientName(client_name, uuid); } void ClientHasSessionCallback(const char* client_name, int* result) { *result = fEngine->ClientHasSessionCallback(client_name); } }; } // end of namespace #endif 1.9.12~dfsg/common/JackPortType.cpp0000644000000000000000000000301513214314510015712 0ustar rootroot/* Copyright (C) 2007 Dmitry Baikov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackPortType.h" #include #include namespace Jack { static const JackPortType* gPortTypes[] = { &gAudioPortType, &gMidiPortType, }; jack_port_type_id_t PORT_TYPES_MAX = sizeof(gPortTypes) / sizeof(gPortTypes[0]); jack_port_type_id_t GetPortTypeId(const char* port_type) { for (jack_port_type_id_t i = 0; i < PORT_TYPES_MAX; ++i) { const JackPortType* type = gPortTypes[i]; assert(type != 0); if (strcmp(port_type, type->fName) == 0) { return i; } } return PORT_TYPES_MAX; } const JackPortType* GetPortType(jack_port_type_id_t type_id) { assert(type_id >= 0 && type_id <= PORT_TYPES_MAX); const JackPortType* type = gPortTypes[type_id]; assert(type != 0); return type; } } // namespace Jack 1.9.12~dfsg/common/JackTypes.h0000644000000000000000000000254113214314510014700 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: JackTypes.h,v 1.2.2.1 2006/06/20 14:44:00 letz Exp $ */ #ifndef __JackTypes__ #define __JackTypes__ #include "types.h" #include "JackCompilerDeps.h" typedef unsigned short UInt16; #if __LP64__ typedef unsigned int UInt32; typedef signed int SInt32; #else typedef unsigned long UInt32; typedef signed long SInt32; #endif #include "JackTypes_os.h" typedef uint16_t jack_int_t; // Internal type for ports and refnum typedef enum { JACK_TIMER_SYSTEM_CLOCK, JACK_TIMER_HPET, } jack_timer_type_t; typedef enum { NotTriggered, Triggered, Running, Finished, } jack_client_state_t; #endif 1.9.12~dfsg/common/JackServer.cpp0000644000000000000000000003271313214314510015401 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackServerGlobals.h" #include "JackTime.h" #include "JackFreewheelDriver.h" #include "JackThreadedDriver.h" #include "JackGlobals.h" #include "JackLockedEngine.h" #include "JackAudioDriver.h" #include "JackChannel.h" #include "JackClientControl.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackInternalClient.h" #include "JackError.h" #include "JackMessageBuffer.h" #include "JackInternalSessionLoader.h" const char * jack_get_self_connect_mode_description(char mode); namespace Jack { //---------------- // Server control //---------------- JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, char self_connect_mode, const char* server_name) { if (rt) { jack_info("JACK server starting in realtime mode with priority %ld", priority); } else { jack_info("JACK server starting in non-realtime mode"); } jack_info("self-connect-mode is \"%s\"", jack_get_self_connect_mode_description(self_connect_mode)); fGraphManager = JackGraphManager::Allocate(port_max); fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl, self_connect_mode); // A distinction is made between the threaded freewheel driver and the // regular freewheel driver because the freewheel driver needs to run in // threaded mode when freewheel mode is active and needs to run as a slave // when freewheel mode isn't active. JackFreewheelDriver* freewheelDriver = new JackFreewheelDriver(fEngine, GetSynchroTable()); fThreadedFreewheelDriver = new JackThreadedDriver(freewheelDriver); fFreewheelDriver = freewheelDriver; fDriverInfo = new JackDriverInfo(); fAudioDriver = NULL; fFreewheel = false; JackServerGlobals::fInstance = this; // Unique instance JackServerGlobals::fUserCount = 1; // One user JackGlobals::fVerbose = verbose; } JackServer::~JackServer() { JackGraphManager::Destroy(fGraphManager); delete fDriverInfo; delete fThreadedFreewheelDriver; delete fEngine; delete fEngineControl; } int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) { // TODO: move that in reworked JackServerGlobals::Init() if (!JackMessageBuffer::Create()) { jack_error("Cannot create message buffer"); } if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) { jack_error("Cannot initialize driver"); goto fail_close1; } if (fRequestChannel.Open(fEngineControl->fServerName, this) < 0) { jack_error("Server channel open error"); goto fail_close2; } if (fEngine->Open() < 0) { jack_error("Cannot open engine"); goto fail_close3; } if (fFreewheelDriver->Open() < 0) { jack_error("Cannot open freewheel driver"); goto fail_close4; } if (fAudioDriver->Attach() < 0) { jack_error("Cannot attach audio driver"); goto fail_close5; } fFreewheelDriver->SetMaster(false); fAudioDriver->SetMaster(true); fAudioDriver->AddSlave(fFreewheelDriver); InitTime(); SetClockSource(fEngineControl->fClockSource); return 0; fail_close5: fFreewheelDriver->Close(); fail_close4: fEngine->Close(); fail_close3: fRequestChannel.Close(); fail_close2: fAudioDriver->Close(); fail_close1: JackMessageBuffer::Destroy(); return -1; } int JackServer::Close() { jack_log("JackServer::Close"); fRequestChannel.Close(); fAudioDriver->Detach(); fAudioDriver->Close(); fFreewheelDriver->Close(); fEngine->Close(); // TODO: move that in reworked JackServerGlobals::Destroy() JackMessageBuffer::Destroy(); EndTime(); return 0; } int JackServer::Start() { jack_log("JackServer::Start"); if (fAudioDriver->Start() < 0) { return -1; } return fRequestChannel.Start(); } int JackServer::Stop() { jack_log("JackServer::Stop"); int res = -1; if (fFreewheel) { if (fThreadedFreewheelDriver) { res = fThreadedFreewheelDriver->Stop(); } } else { if (fAudioDriver) { res = fAudioDriver->Stop(); } } fEngine->NotifyQuit(); fRequestChannel.Stop(); fEngine->NotifyFailure(JackFailure | JackServerError, JACK_SERVER_FAILURE); return res; } bool JackServer::IsRunning() { jack_log("JackServer::IsRunning"); assert(fAudioDriver); return fAudioDriver->IsRunning(); } //------------------ // Internal clients //------------------ int JackServer::InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status) { JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data); assert(client); return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); } int JackServer::InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status) { JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters); assert(client); return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); } int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status) { // Clear status *status = 0; // Client object is internally kept in JackEngine if ((client->Init(so_name) < 0) || (client->Open(JackTools::DefaultServerName(), client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) { delete client; int my_status1 = *status | JackFailure; *status = (jack_status_t)my_status1; *int_ref = 0; return -1; } else { *int_ref = client->GetClientControl()->fRefNum; return 0; } } //----------------------- // Internal session file //----------------------- int JackServer::LoadInternalSessionFile(const char* file) { JackInternalSessionLoader loader(this); return loader.Load(file); } //--------------------------- // From request thread : API //--------------------------- int JackServer::SetBufferSize(jack_nframes_t buffer_size) { jack_log("JackServer::SetBufferSize nframes = %ld", buffer_size); jack_nframes_t current_buffer_size = fEngineControl->fBufferSize; if (current_buffer_size == buffer_size) { jack_log("SetBufferSize: requirement for new buffer size equals current value"); return 0; } if (fAudioDriver->IsFixedBufferSize()) { jack_log("SetBufferSize: driver only supports a fixed buffer size"); return -1; } if (fAudioDriver->Stop() != 0) { jack_error("Cannot stop audio driver"); return -1; } if (fAudioDriver->SetBufferSize(buffer_size) == 0) { fEngine->NotifyBufferSize(buffer_size); return fAudioDriver->Start(); } else { // Failure: try to restore current value jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size); fAudioDriver->SetBufferSize(current_buffer_size); fAudioDriver->Start(); // SetBufferSize actually failed, so return an error... return -1; } } /* Freewheel mode is implemented by switching from the (audio [slaves] + freewheel) driver to the freewheel driver only: - "global" connection state is saved - all audio driver and slaves ports are deconnected, thus there is no more dependancies with the audio driver and slaves - the freewheel driver will be synchronized with the end of graph execution : all clients are connected to the freewheel driver - the freewheel driver becomes the "master" Normal mode is restored with the connections state valid before freewheel mode was done. Thus one consider that no graph state change can be done during freewheel mode. */ int JackServer::SetFreewheel(bool onoff) { jack_log("JackServer::SetFreewheel is = %ld want = %ld", fFreewheel, onoff); if (fFreewheel) { if (onoff) { return -1; } else { fFreewheel = false; fThreadedFreewheelDriver->Stop(); fGraphManager->Restore(&fConnectionState); // Restore connection state fEngine->NotifyFreewheel(onoff); fFreewheelDriver->SetMaster(false); fAudioDriver->SetMaster(true); return fAudioDriver->Start(); } } else { if (onoff) { fFreewheel = true; fAudioDriver->Stop(); fGraphManager->Save(&fConnectionState); // Save connection state // Disconnect all slaves std::list slave_list = fAudioDriver->GetSlaves(); std::list::const_iterator it; for (it = slave_list.begin(); it != slave_list.end(); it++) { JackDriver* slave = dynamic_cast(*it); assert(slave); fGraphManager->DisconnectAllPorts(slave->GetClientControl()->fRefNum); } // Disconnect master fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum); fEngine->NotifyFreewheel(onoff); fAudioDriver->SetMaster(false); fFreewheelDriver->SetMaster(true); return fThreadedFreewheelDriver->Start(); } else { return -1; } } } //--------------------------- // Coming from the RT thread //--------------------------- void JackServer::Notify(int refnum, int notify, int value) { switch (notify) { case kGraphOrderCallback: fEngine->NotifyGraphReorder(); break; case kXRunCallback: fEngine->NotifyClientXRun(refnum); break; } } //-------------------- // Backend management //-------------------- JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params) { JackDriverInfo* info = new JackDriverInfo(); JackDriverClientInterface* slave = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); if (!slave) { goto error1; } if (slave->Attach() < 0) { goto error2; } slave->SetMaster(false); fAudioDriver->AddSlave(slave); return info; error2: slave->Close(); error1: delete info; return NULL; } void JackServer::RemoveSlave(JackDriverInfo* info) { JackDriverClientInterface* slave = info->GetBackend(); fAudioDriver->RemoveSlave(slave); slave->Detach(); slave->Close(); } int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params) { std::list slave_list; std::list::const_iterator it; // Remove current master fAudioDriver->Stop(); fAudioDriver->Detach(); fAudioDriver->Close(); // Open new master JackDriverInfo* info = new JackDriverInfo(); JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); if (!master) { goto error; } // Get slaves list slave_list = fAudioDriver->GetSlaves(); // Move slaves in new master for (it = slave_list.begin(); it != slave_list.end(); it++) { JackDriverInterface* slave = *it; master->AddSlave(slave); } // Delete old master delete fDriverInfo; // Activate master fAudioDriver = master; fDriverInfo = info; if (fAudioDriver->Attach() < 0) { goto error; } // Notify clients of new values fEngine->NotifyBufferSize(fEngineControl->fBufferSize); fEngine->NotifySampleRate(fEngineControl->fSampleRate); // And finally start fAudioDriver->SetMaster(true); return fAudioDriver->Start(); error: delete info; return -1; } //---------------------- // Transport management //---------------------- int JackServer::ReleaseTimebase(int refnum) { return fEngineControl->fTransport.ResetTimebase(refnum); } int JackServer::SetTimebaseCallback(int refnum, int conditional) { return fEngineControl->fTransport.SetTimebaseMaster(refnum, conditional); } JackLockedEngine* JackServer::GetEngine() { return fEngine; } JackSynchro* JackServer::GetSynchroTable() { return fSynchroTable; } JackEngineControl* JackServer::GetEngineControl() { return fEngineControl; } JackGraphManager* JackServer::GetGraphManager() { return fGraphManager; } } // end of namespace 1.9.12~dfsg/common/JackDriverLoader.h0000644000000000000000000000245113214314510016156 0ustar rootroot/* Copyright (C) 2001-2005 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackDriverLoader__ #define __JackDriverLoader__ #include "driver_interface.h" #include "JackControlAPI.h" #include "JackPlatformPlug.h" jack_driver_desc_t* jack_find_driver_descriptor(JSList* drivers, const char* name); JSList* jack_drivers_load(JSList* drivers); JSList* jack_internals_load(JSList* internals); void jack_free_driver_params(JSList * param_ptr); void jack_print_driver_options(jack_driver_desc_t* desc, FILE* file); // External control.h API extern "C" SERVER_EXPORT int jackctl_driver_params_parse(jackctl_driver * driver, int argc, char* argv[]); #endif 1.9.12~dfsg/common/JackNetInterface.cpp0000644000000000000000000010454013214314510016500 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackNetInterface.h" #include "JackException.h" #include "JackError.h" #include using namespace std; /* TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames, probably also use BUFFER_SIZE_MAX in everything related to MIDI events handling (see MidiBufferInit in JackMidiPort.cpp) */ namespace Jack { // JackNetInterface******************************************* JackNetInterface::JackNetInterface() : fSocket() { Initialize(); } JackNetInterface::JackNetInterface(const char* multicast_ip, int port) : fSocket(multicast_ip, port) { strcpy(fMulticastIP, multicast_ip); Initialize(); } JackNetInterface::JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip) : fSocket(socket) { fParams = params; strcpy(fMulticastIP, multicast_ip); Initialize(); } void JackNetInterface::Initialize() { fSetTimeOut = false; fTxBuffer = NULL; fRxBuffer = NULL; fNetAudioCaptureBuffer = NULL; fNetAudioPlaybackBuffer = NULL; fNetMidiCaptureBuffer = NULL; fNetMidiPlaybackBuffer = NULL; memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); fPacketTimeOut = PACKET_TIMEOUT * NETWORK_DEFAULT_LATENCY; } void JackNetInterface::FreeNetworkBuffers() { delete fNetMidiCaptureBuffer; delete fNetMidiPlaybackBuffer; delete fNetAudioCaptureBuffer; delete fNetAudioPlaybackBuffer; fNetMidiCaptureBuffer = NULL; fNetMidiPlaybackBuffer = NULL; fNetAudioCaptureBuffer = NULL; fNetAudioPlaybackBuffer = NULL; } JackNetInterface::~JackNetInterface() { jack_log("JackNetInterface::~JackNetInterface"); fSocket.Close(); delete[] fTxBuffer; delete[] fRxBuffer; delete fNetAudioCaptureBuffer; delete fNetAudioPlaybackBuffer; delete fNetMidiCaptureBuffer; delete fNetMidiPlaybackBuffer; } int JackNetInterface::SetNetBufferSize() { // audio float audio_size = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->GetCycleSize() : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0; jack_log("audio_size %f", audio_size); // midi float midi_size = (fNetMidiCaptureBuffer) ? fNetMidiCaptureBuffer->GetCycleSize() : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0; jack_log("midi_size %f", midi_size); // bufsize = sync + audio + midi int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int)midi_size); jack_log("SetNetBufferSize bufsize = %d", bufsize); // tx buffer if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) { return SOCKET_ERROR; } // rx buffer if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) { return SOCKET_ERROR; } return 0; } bool JackNetInterface::SetParams() { // TX header init memset(&fTxHeader, 0, sizeof(fTxHeader)); strcpy(fTxHeader.fPacketType, "header"); fTxHeader.fID = fParams.fID; fTxHeader.fCycle = 0; fTxHeader.fSubCycle = 0; fTxHeader.fIsLastPckt = 0; // RX header init memset(&fRxHeader, 0, sizeof(fTxHeader)); strcpy(fRxHeader.fPacketType, "header"); fRxHeader.fID = fParams.fID; fRxHeader.fCycle = 0; fRxHeader.fSubCycle = 0; fRxHeader.fIsLastPckt = 0; // network buffers fTxBuffer = new char[fParams.fMtu]; fRxBuffer = new char[fParams.fMtu]; assert(fTxBuffer); assert(fRxBuffer); // net audio/midi buffers'addresses fTxData = fTxBuffer + HEADER_SIZE; fRxData = fRxBuffer + HEADER_SIZE; return true; } int JackNetInterface::MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels) { if (midi_channnels > 0) { // set global header fields and get the number of midi packets fTxHeader.fDataType = 'm'; uint data_size = buffer->RenderFromJackPorts(); fTxHeader.fNumPacket = buffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE(&fParams)); for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) { fTxHeader.fSubCycle = subproc; fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && audio_channels == 0) ? 1 : 0; fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, data_size); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); //PacketHeaderDisplay(&fTxHeader); if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) { return SOCKET_ERROR; } } } return 0; } int JackNetInterface::AudioSend(NetAudioBuffer* buffer, int audio_channels) { // audio if (audio_channels > 0) { fTxHeader.fDataType = 'a'; fTxHeader.fActivePorts = buffer->RenderFromJackPorts(fTxHeader.fFrames); fTxHeader.fNumPacket = buffer->GetNumPackets(fTxHeader.fActivePorts); for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) { fTxHeader.fSubCycle = subproc; fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0; fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, fTxHeader.fActivePorts); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); //PacketHeaderDisplay(&fTxHeader); if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) { return SOCKET_ERROR; } } } return 0; } int JackNetInterface::MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt) { int rx_bytes = Recv(rx_head->fPacketSize, 0); fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; buffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); // Last midi packet is received, so finish rendering... if (++recvd_midi_pckt == rx_head->fNumPacket) { buffer->RenderToJackPorts(); } //PacketHeaderDisplay(rx_head); return rx_bytes; } int JackNetInterface::AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer) { int rx_bytes = Recv(rx_head->fPacketSize, 0); fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fRxHeader.fActivePorts = rx_head->fActivePorts; fRxHeader.fFrames = rx_head->fFrames; rx_bytes = buffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, fRxHeader.fActivePorts); // Last audio packet is received, so finish rendering... if (fRxHeader.fIsLastPckt) { buffer->RenderToJackPorts(fRxHeader.fFrames); } //PacketHeaderDisplay(rx_head); return rx_bytes; } int JackNetInterface::FinishRecv(NetAudioBuffer* buffer) { if (buffer) { buffer->RenderToJackPorts(fRxHeader.fFrames); } else { jack_error("FinishRecv with null buffer..."); } return DATA_PACKET_ERROR; } NetAudioBuffer* JackNetInterface::AudioBufferFactory(int nports, char* buffer) { switch (fParams.fSampleEncoder) { case JackFloatEncoder: return new NetFloatAudioBuffer(&fParams, nports, buffer); case JackIntEncoder: return new NetIntAudioBuffer(&fParams, nports, buffer); #if HAVE_CELT case JackCeltEncoder: return new NetCeltAudioBuffer(&fParams, nports, buffer, fParams.fKBps); #endif #if HAVE_OPUS case JackOpusEncoder: return new NetOpusAudioBuffer(&fParams, nports, buffer, fParams.fKBps); #endif } throw std::bad_alloc(); } void JackNetInterface::SetRcvTimeOut() { if (!fSetTimeOut) { if (fSocket.SetTimeOut(fPacketTimeOut) == SOCKET_ERROR) { jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); return; } fSetTimeOut = true; } } // JackNetMasterInterface ************************************************************************************ bool JackNetMasterInterface::Init() { jack_log("JackNetMasterInterface::Init : ID %u", fParams.fID); session_params_t host_params; uint attempt = 0; int rx_bytes = 0; // socket if (fSocket.NewSocket() == SOCKET_ERROR) { jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE)); return false; } // timeout on receive (for init) if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0) { jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE)); } // connect if (fSocket.Connect() == SOCKET_ERROR) { jack_error("Can't connect : %s", StrError(NET_ERROR_CODE)); return false; } // send 'SLAVE_SETUP' until 'START_MASTER' received jack_info("Sending parameters to %s...", fParams.fSlaveNetName); do { session_params_t net_params; memset(&net_params, 0, sizeof(session_params_t)); SetPacketType(&fParams, SLAVE_SETUP); SessionParamsHToN(&fParams, &net_params); if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) { jack_error("Error in send : %s", StrError(NET_ERROR_CODE)); } memset(&net_params, 0, sizeof(session_params_t)); if (((rx_bytes = fSocket.Recv(&net_params, sizeof(session_params_t), 0)) == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { jack_error("Problem with network"); return false; } SessionParamsNToH(&net_params, &host_params); } while ((GetPacketType(&host_params) != START_MASTER) && (++attempt < SLAVE_SETUP_RETRY)); if (attempt == SLAVE_SETUP_RETRY) { jack_error("Slave doesn't respond, exiting"); return false; } return true; } bool JackNetMasterInterface::SetParams() { jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d", fParams.fSendAudioChannels, fParams.fReturnAudioChannels, fParams.fSendMidiChannels, fParams.fReturnMidiChannels); JackNetInterface::SetParams(); fTxHeader.fDataStream = 's'; fRxHeader.fDataStream = 'r'; fMaxCycleOffset = fParams.fNetworkLatency; // midi net buffers if (fParams.fSendMidiChannels > 0) { fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData); } if (fParams.fReturnMidiChannels > 0) { fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fRxData); } try { // audio net buffers if (fParams.fSendAudioChannels > 0) { fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fTxData); assert(fNetAudioCaptureBuffer); } if (fParams.fReturnAudioChannels > 0) { fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fRxData); assert(fNetAudioPlaybackBuffer); } } catch (exception&) { jack_error("NetAudioBuffer on master allocation error..."); return false; } // set the new buffer size if (SetNetBufferSize() == SOCKET_ERROR) { jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE)); goto error; } return true; error: FreeNetworkBuffers(); return false; } void JackNetMasterInterface::Exit() { jack_log("JackNetMasterInterface::Exit, ID %u", fParams.fID); // stop process fRunning = false; // send a 'multicast euthanasia request' - new socket is required on macosx jack_info("Exiting '%s' %s", fParams.fName, fMulticastIP); SetPacketType(&fParams, KILL_MASTER); JackNetSocket mcast_socket(fMulticastIP, fSocket.GetPort()); session_params_t net_params; memset(&net_params, 0, sizeof(session_params_t)); SessionParamsHToN(&fParams, &net_params); if (mcast_socket.NewSocket() == SOCKET_ERROR) { jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE)); } if (mcast_socket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) { jack_error("Can't send suicide request : %s", StrError(NET_ERROR_CODE)); } mcast_socket.Close(); } void JackNetMasterInterface::FatalRecvError() { // fatal connection issue, exit jack_error("Recv connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName); // ask to the manager to properly remove the master Exit(); // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. ThreadExit(); } void JackNetMasterInterface::FatalSendError() { // fatal connection issue, exit jack_error("Send connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName); // ask to the manager to properly remove the master Exit(); // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. ThreadExit(); } int JackNetMasterInterface::Recv(size_t size, int flags) { int rx_bytes; if (((rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) { FatalRecvError(); } packet_header_t* header = reinterpret_cast(fRxBuffer); PacketHeaderNToH(header, header); return rx_bytes; } int JackNetMasterInterface::Send(size_t size, int flags) { int tx_bytes; packet_header_t* header = reinterpret_cast(fTxBuffer); PacketHeaderHToN(header, header); if (((tx_bytes = fSocket.Send(fTxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) { FatalSendError(); } return tx_bytes; } int JackNetMasterInterface::SyncSend() { SetRcvTimeOut(); fTxHeader.fCycle++; fTxHeader.fSubCycle = 0; fTxHeader.fDataType = 's'; fTxHeader.fIsLastPckt = (fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0; fTxHeader.fPacketSize = HEADER_SIZE + fTxHeader.fActivePorts * sizeof(int); // Data part is used to encode active ports memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); //PacketHeaderDisplay(&fTxHeader); return Send(fTxHeader.fPacketSize, 0); } int JackNetMasterInterface::DataSend() { if (MidiSend(fNetMidiCaptureBuffer, fParams.fSendMidiChannels, fParams.fSendAudioChannels) == SOCKET_ERROR) { return SOCKET_ERROR; } return AudioSend(fNetAudioCaptureBuffer, fParams.fSendAudioChannels); } int JackNetMasterInterface::SyncRecv() { int rx_bytes = 0; packet_header_t* rx_head = reinterpret_cast(fRxBuffer); // receive sync (launch the cycle) do { rx_bytes = Recv(fParams.fMtu, MSG_PEEK); // connection issue (return -1) if (rx_bytes == SOCKET_ERROR) { return SOCKET_ERROR; } } while (strcmp(rx_head->fPacketType, "header") != 0); //PacketHeaderDisplay(rx_head); if (rx_head->fDataType != 's') { jack_error("Wrong packet type : %c", rx_head->fDataType); // not the last packet.. fRxHeader.fIsLastPckt = 0; return SYNC_PACKET_ERROR; } fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle; if (fCurrentCycleOffset < fMaxCycleOffset && !fSynched) { jack_info("Synching with latency = %d", fCurrentCycleOffset); return NET_SYNCHING; } else { if (fCurrentCycleOffset == fMaxCycleOffset) { // when the sync offset is reached fSynched = true; } rx_bytes = Recv(rx_head->fPacketSize, 0); fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; return rx_bytes; } } int JackNetMasterInterface::DataRecv() { int rx_bytes = 0; uint recvd_midi_pckt = 0; packet_header_t* rx_head = reinterpret_cast(fRxBuffer); while (!fRxHeader.fIsLastPckt) { // how much data is queued on the rx buffer ? rx_bytes = Recv(fParams.fMtu, MSG_PEEK); // error here, problem with recv, just skip the cycle (return -1) if (rx_bytes == SOCKET_ERROR) { return rx_bytes; } if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID)) { // read data switch (rx_head->fDataType) { case 'm': // midi rx_bytes = MidiRecv(rx_head, fNetMidiPlaybackBuffer, recvd_midi_pckt); break; case 'a': // audio rx_bytes = AudioRecv(rx_head, fNetAudioPlaybackBuffer); break; case 's': // sync jack_info("NetMaster : missing last data packet from '%s'", fParams.fName); return FinishRecv(fNetAudioPlaybackBuffer); } } } return rx_bytes; } void JackNetMasterInterface::EncodeSyncPacket(int frames) { // This method contains every step of sync packet informations coding // first of all, clear sync packet memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams)); // Transport not used for now... /* // then, first step : transport if (fParams.fTransportSync) { EncodeTransportData(); TransportDataHToN(&fSendTransportData, &fSendTransportData); // copy to TxBuffer memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t)); } // then others (freewheel etc.) // ... */ // Write active ports list fTxHeader.fActivePorts = (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData) : 0; fTxHeader.fFrames = frames; } void JackNetMasterInterface::DecodeSyncPacket(int& frames) { // This method contains every step of sync packet informations decoding process // Transport not used for now... /* // first : transport if (fParams.fTransportSync) { // copy received transport data to transport data structure memcpy(&fReturnTransportData, fRxData, sizeof(net_transport_data_t)); TransportDataNToH(&fReturnTransportData, &fReturnTransportData); DecodeTransportData(); } // then others // ... */ packet_header_t* rx_head = reinterpret_cast(fRxBuffer); // Read active ports list if (fNetAudioCaptureBuffer) { fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts); } frames = rx_head->fFrames; } // JackNetSlaveInterface ************************************************************************************************ uint JackNetSlaveInterface::fSlaveCounter = 0; void JackNetSlaveInterface::InitAPI() { // open Socket API with the first slave if (fSlaveCounter++ == 0) { if (SocketAPIInit() < 0) { jack_error("Can't init Socket API, exiting..."); throw std::bad_alloc(); } } } bool JackNetSlaveInterface::Init() { jack_log("JackNetSlaveInterface::Init()"); // set the parameters to send strcpy(fParams.fPacketType, "params"); fParams.fProtocolVersion = NETWORK_PROTOCOL; SetPacketType(&fParams, SLAVE_AVAILABLE); // init loop : get a master and start, do it until connection is ok net_status_t status; do { // first, get a master, do it until a valid connection is running do { status = SendAvailableToMaster(); if (status == NET_SOCKET_ERROR) { return false; } } while (status != NET_CONNECTED); // then tell the master we are ready jack_info("Initializing connection with %s...", fParams.fMasterNetName); status = SendStartToMaster(); if (status == NET_ERROR) { return false; } } while (status != NET_ROLLING); return true; } // Separate the connection protocol into two separated step bool JackNetSlaveInterface::InitConnection(int time_out_sec) { jack_log("JackNetSlaveInterface::InitConnection time_out_sec = %d", time_out_sec); int try_count = (time_out_sec > 0) ? int((1000000.f * float(time_out_sec)) / float(SLAVE_INIT_TIMEOUT)) : INT_MAX; // set the parameters to send strcpy(fParams.fPacketType, "params"); fParams.fProtocolVersion = NETWORK_PROTOCOL; SetPacketType(&fParams, SLAVE_AVAILABLE); return (SendAvailableToMaster(try_count) == NET_CONNECTED); } bool JackNetSlaveInterface::InitRendering() { jack_log("JackNetSlaveInterface::InitRendering()"); net_status_t status; do { // then tell the master we are ready jack_info("Initializing connection with %s...", fParams.fMasterNetName); status = SendStartToMaster(); if (status == NET_ERROR) { return false; } } while (status != NET_ROLLING); return true; } net_status_t JackNetSlaveInterface::SendAvailableToMaster(int try_count) { jack_log("JackNetSlaveInterface::SendAvailableToMaster try_count = %d", try_count); // utility session_params_t host_params; int rx_bytes = 0; // socket if (fSocket.NewSocket() == SOCKET_ERROR) { jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE)); return NET_SOCKET_ERROR; } if (fSocket.IsLocal(fMulticastIP)) { jack_info("Local IP is used..."); } else { // bind the socket if (fSocket.Bind() == SOCKET_ERROR) { jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE)); return NET_SOCKET_ERROR; } } // timeout on receive (for init) if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR) { jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE)); } // disable local loop if (fSocket.SetLocalLoop() == SOCKET_ERROR) { jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE)); } // send 'AVAILABLE' until 'SLAVE_SETUP' received jack_info("Waiting for a master..."); do { // send 'available' session_params_t net_params; memset(&net_params, 0, sizeof(session_params_t)); SessionParamsHToN(&fParams, &net_params); if (fSocket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) { jack_error("Error in data send : %s", StrError(NET_ERROR_CODE)); } // filter incoming packets : don't exit while no error is detected memset(&net_params, 0, sizeof(session_params_t)); rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0); SessionParamsNToH(&net_params, &host_params); if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { jack_error("Can't receive : %s", StrError(NET_ERROR_CODE)); return NET_RECV_ERROR; } } while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--try_count > 0)); // time out failure.. if (try_count == 0) { jack_error("Time out error in connect"); return NET_CONNECT_ERROR; } // everything is OK, copy parameters fParams = host_params; // connect the socket if (fSocket.Connect() == SOCKET_ERROR) { jack_error("Error in connect : %s", StrError(NET_ERROR_CODE)); return NET_CONNECT_ERROR; } return NET_CONNECTED; } net_status_t JackNetSlaveInterface::SendStartToMaster() { jack_log("JackNetSlaveInterface::SendStartToMaster"); // tell the master to start session_params_t net_params; memset(&net_params, 0, sizeof(session_params_t)); SetPacketType(&fParams, START_MASTER); SessionParamsHToN(&fParams, &net_params); if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) { jack_error("Error in send : %s", StrError(NET_ERROR_CODE)); return (fSocket.GetError() == NET_CONN_ERROR) ? NET_ERROR : NET_SEND_ERROR; } return NET_ROLLING; } bool JackNetSlaveInterface::SetParams() { jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d", fParams.fSendAudioChannels, fParams.fReturnAudioChannels, fParams.fSendMidiChannels, fParams.fReturnMidiChannels); JackNetInterface::SetParams(); fTxHeader.fDataStream = 'r'; fRxHeader.fDataStream = 's'; // midi net buffers if (fParams.fSendMidiChannels > 0) { fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fRxData); } if (fParams.fReturnMidiChannels > 0) { fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fTxData); } try { // audio net buffers if (fParams.fSendAudioChannels > 0) { fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fRxData); assert(fNetAudioCaptureBuffer); } if (fParams.fReturnAudioChannels > 0) { fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fTxData); assert(fNetAudioPlaybackBuffer); } } catch (exception&) { jack_error("NetAudioBuffer on slave allocation error..."); return false; } // set the new buffer sizes if (SetNetBufferSize() == SOCKET_ERROR) { jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE)); goto error; } return true; error: FreeNetworkBuffers(); return false; } void JackNetSlaveInterface::FatalRecvError() { throw JackNetException("Recv connection lost error"); } void JackNetSlaveInterface::FatalSendError() { throw JackNetException("Send connection lost error"); } int JackNetSlaveInterface::Recv(size_t size, int flags) { int rx_bytes = fSocket.Recv(fRxBuffer, size, flags); // handle errors if (rx_bytes == SOCKET_ERROR) { FatalRecvError(); } packet_header_t* header = reinterpret_cast(fRxBuffer); PacketHeaderNToH(header, header); return rx_bytes; } int JackNetSlaveInterface::Send(size_t size, int flags) { packet_header_t* header = reinterpret_cast(fTxBuffer); PacketHeaderHToN(header, header); int tx_bytes = fSocket.Send(fTxBuffer, size, flags); // handle errors if (tx_bytes == SOCKET_ERROR) { FatalSendError(); } return tx_bytes; } int JackNetSlaveInterface::SyncRecv() { SetRcvTimeOut(); int rx_bytes = 0; packet_header_t* rx_head = reinterpret_cast(fRxBuffer); // receive sync (launch the cycle) do { rx_bytes = Recv(fParams.fMtu, 0); // connection issue (return -1) if (rx_bytes == SOCKET_ERROR) { return rx_bytes; } } while (strcmp(rx_head->fPacketType, "header") != 0); if (rx_head->fDataType != 's') { jack_error("Wrong packet type : %c", rx_head->fDataType); // not the last packet... fRxHeader.fIsLastPckt = 0; return SYNC_PACKET_ERROR; } //PacketHeaderDisplay(rx_head); fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; return rx_bytes; } int JackNetSlaveInterface::DataRecv() { int rx_bytes = 0; uint recvd_midi_pckt = 0; packet_header_t* rx_head = reinterpret_cast(fRxBuffer); while (!fRxHeader.fIsLastPckt) { // how much data is queued on the rx buffer ? rx_bytes = Recv(fParams.fMtu, MSG_PEEK); // error here, just skip the cycle (return -1) if (rx_bytes == SOCKET_ERROR) { return rx_bytes; } if (rx_bytes && (rx_head->fDataStream == 's') && (rx_head->fID == fParams.fID)) { // read data switch (rx_head->fDataType) { case 'm': // midi rx_bytes = MidiRecv(rx_head, fNetMidiCaptureBuffer, recvd_midi_pckt); break; case 'a': // audio rx_bytes = AudioRecv(rx_head, fNetAudioCaptureBuffer); break; case 's': // sync jack_info("NetSlave : missing last data packet"); return FinishRecv(fNetAudioCaptureBuffer); } } } fRxHeader.fCycle = rx_head->fCycle; return rx_bytes; } int JackNetSlaveInterface::SyncSend() { // tx header if (fParams.fSlaveSyncMode) { fTxHeader.fCycle = fRxHeader.fCycle; } else { fTxHeader.fCycle++; } fTxHeader.fSubCycle = 0; fTxHeader.fDataType = 's'; fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0; fTxHeader.fPacketSize = HEADER_SIZE + fTxHeader.fActivePorts * sizeof(int); // Data part is used to encode active ports memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); //PacketHeaderDisplay(&fTxHeader); return Send(fTxHeader.fPacketSize, 0); } int JackNetSlaveInterface::DataSend() { if (MidiSend(fNetMidiPlaybackBuffer, fParams.fReturnMidiChannels, fParams.fReturnAudioChannels) == SOCKET_ERROR) { return SOCKET_ERROR; } return AudioSend(fNetAudioPlaybackBuffer, fParams.fReturnAudioChannels); } // network sync------------------------------------------------------------------------ void JackNetSlaveInterface::EncodeSyncPacket(int frames) { // This method contains every step of sync packet informations coding // first of all, clear sync packet memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams)); // then first step : transport // Transport is not used for now... /* if (fParams.fTransportSync) { EncodeTransportData(); TransportDataHToN(&fReturnTransportData, &fReturnTransportData); // copy to TxBuffer memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t)); } // then others // ... */ // Write active ports list fTxHeader.fActivePorts = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData) : 0; fTxHeader.fFrames = frames; } void JackNetSlaveInterface::DecodeSyncPacket(int& frames) { // This method contains every step of sync packet informations decoding process // Transport not used for now... /* // first : transport if (fParams.fTransportSync) { // copy received transport data to transport data structure memcpy(&fSendTransportData, fRxData, sizeof(net_transport_data_t)); TransportDataNToH(&fSendTransportData, &fSendTransportData); DecodeTransportData(); } // then others // ... */ packet_header_t* rx_head = reinterpret_cast(fRxBuffer); // Read active ports list if (fNetAudioPlaybackBuffer) { fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts); } frames = rx_head->fFrames; } } 1.9.12~dfsg/common/JackMidiUtil.h0000644000000000000000000000647113214314510015322 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiUtil__ #define __JackMidiUtil__ #include "JackMidiPort.h" namespace Jack { /** * Use this function to optimize MIDI output by omitting unnecessary status * bytes. This can't be used with all MIDI APIs, so before using this * function, make sure that your MIDI API doesn't require complete MIDI * messages to be sent. * * To start using this function, call this method with pointers to the * `size` and `buffer` arguments of the MIDI message you want to send, and * set the `running_status` argument to '0'. For each subsequent MIDI * message, call this method with pointers to its `size` and `buffer` * arguments, and set the `running_status` argument to the return value of * the previous call to this function. * * Note: This function will alter the `size` and `buffer` of your MIDI * message for each message that can be optimized. */ SERVER_EXPORT jack_midi_data_t ApplyRunningStatus(size_t *size, jack_midi_data_t **buffer, jack_midi_data_t running_status=0); /** * A wrapper function for the above `ApplyRunningStatus` function. */ SERVER_EXPORT jack_midi_data_t ApplyRunningStatus(jack_midi_event_t *event, jack_midi_data_t running_status); /** * Gets the estimated current time in frames. This function has the same * functionality as the JACK client API function `jack_frame_time`. */ SERVER_EXPORT jack_nframes_t GetCurrentFrame(); /** * Gets the estimated frame that will be occurring at the given time. This * function has the same functionality as the JACK client API function * `jack_time_to_frames`. */ SERVER_EXPORT jack_nframes_t GetFramesFromTime(jack_time_t time); /** * Gets the precise time at the start of the current process cycle. This * function has the same functionality as the JACK client API function * `jack_last_frame_time`. */ SERVER_EXPORT jack_nframes_t GetLastFrame(); /** * Returns the expected message length for the status byte. Returns 0 if * the status byte is a system exclusive status byte, or -1 if the status * byte is invalid. */ SERVER_EXPORT int GetMessageLength(jack_midi_data_t status_byte); /** * Gets the estimated time at which the given frame will occur. This * function has the same functionality as the JACK client API function * `jack_frames_to_time`. */ SERVER_EXPORT jack_time_t GetTimeFromFrames(jack_nframes_t frames); }; #endif 1.9.12~dfsg/common/JackTools.cpp0000644000000000000000000001774613214314510015244 0ustar rootroot/* Copyright (C) 2006-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackConstants.h" #include "JackDriverLoader.h" #include "JackTools.h" #include "JackError.h" #include #include #include #include #ifdef WIN32 #include #endif using namespace std; namespace Jack { void JackTools::KillServer() { #ifdef WIN32 raise(SIGINT); #else kill(GetPID(), SIGINT); #endif } void JackTools::ThrowJackNetException() { throw JackNetException(); } int JackTools::MkDir(const char* path) { #ifdef WIN32 return CreateDirectory(path, NULL) == 0; #else return mkdir(path, 0777) != 0; #endif } #define DEFAULT_TMP_DIR "/tmp" char* jack_tmpdir = (char*)DEFAULT_TMP_DIR; int JackTools::GetPID() { #ifdef WIN32 return _getpid(); #else return getpid(); #endif } int JackTools::GetUID() { #ifdef WIN32 return _getpid(); //#error "No getuid function available" #else return getuid(); #endif } const char* JackTools::DefaultServerName() { const char* server_name; if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) { server_name = JACK_DEFAULT_SERVER_NAME; } return server_name; } /* returns the name of the per-user subdirectory of jack_tmpdir */ #ifdef WIN32 char* JackTools::UserDir() { return ""; } char* JackTools::ServerDir(const char* server_name, char* server_dir) { return ""; } void JackTools::CleanupFiles(const char* server_name) {} int JackTools::GetTmpdir() { return 0; } #else char* JackTools::UserDir() { static char user_dir[JACK_PATH_MAX + 1] = ""; /* format the path name on the first call */ if (user_dir[0] == '\0') { if (getenv ("JACK_PROMISCUOUS_SERVER")) { snprintf(user_dir, sizeof(user_dir), "%s/jack", jack_tmpdir); } else { snprintf(user_dir, sizeof(user_dir), "%s/jack-%d", jack_tmpdir, GetUID()); } } return user_dir; } /* returns the name of the per-server subdirectory of jack_user_dir() */ char* JackTools::ServerDir(const char* server_name, char* server_dir) { /* format the path name into the suppled server_dir char array, * assuming that server_dir is at least as large as JACK_PATH_MAX + 1 */ snprintf(server_dir, JACK_PATH_MAX + 1, "%s/%s", UserDir(), server_name); return server_dir; } void JackTools::CleanupFiles(const char* server_name) { DIR* dir; struct dirent *dirent; char dir_name[JACK_PATH_MAX + 1] = ""; ServerDir(server_name, dir_name); /* On termination, we remove all files that jackd creates so * subsequent attempts to start jackd will not believe that an * instance is already running. If the server crashes or is * terminated with SIGKILL, this is not possible. So, cleanup * is also attempted when jackd starts. * * There are several tricky issues. First, the previous JACK * server may have run for a different user ID, so its files * may be inaccessible. This is handled by using a separate * JACK_TMP_DIR subdirectory for each user. Second, there may * be other servers running with different names. Each gets * its own subdirectory within the per-user directory. The * current process has already registered as `server_name', so * we know there is no other server actively using that name. */ /* nothing to do if the server directory does not exist */ if ((dir = opendir(dir_name)) == NULL) { return; } /* unlink all the files in this directory, they are mine */ while ((dirent = readdir(dir)) != NULL) { char fullpath[JACK_PATH_MAX + 1]; if ((strcmp(dirent->d_name, ".") == 0) || (strcmp (dirent->d_name, "..") == 0)) { continue; } snprintf(fullpath, sizeof(fullpath), "%s/%s", dir_name, dirent->d_name); if (unlink(fullpath)) { jack_error("cannot unlink `%s' (%s)", fullpath, strerror(errno)); } } closedir(dir); /* now, delete the per-server subdirectory, itself */ if (rmdir(dir_name)) { jack_error("cannot remove `%s' (%s)", dir_name, strerror(errno)); } /* finally, delete the per-user subdirectory, if empty */ if (rmdir(UserDir())) { if (errno != ENOTEMPTY) { jack_error("cannot remove `%s' (%s)", UserDir(), strerror(errno)); } } } int JackTools::GetTmpdir() { FILE* in; size_t len; char buf[JACK_PATH_MAX + 2]; /* allow tmpdir to live anywhere, plus newline, plus null */ if ((in = popen("jackd -l", "r")) == NULL) { return -1; } if (fgets(buf, sizeof(buf), in) == NULL) { pclose(in); return -1; } len = strlen(buf); if (buf[len - 1] != '\n') { /* didn't get a whole line */ pclose(in); return -1; } jack_tmpdir = (char *)malloc(len); memcpy(jack_tmpdir, buf, len - 1); jack_tmpdir[len - 1] = '\0'; pclose(in); return 0; } #endif void JackTools::RewriteName(const char* name, char* new_name) { size_t i; for (i = 0; i < strlen(name); i++) { if ((name[i] == '/') || (name[i] == '\\')) { new_name[i] = '_'; } else { new_name[i] = name[i]; } } new_name[i] = '\0'; } #ifdef WIN32 void BuildClientPath(char* path_to_so, int path_len, const char* so_name) { snprintf(path_to_so, path_len, ADDON_DIR "/%s.dll", so_name); } void PrintLoadError(const char* so_name) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message and exit the process lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)so_name) + 40) * sizeof(TCHAR)); _snprintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("error loading %s err = %s"), so_name, lpMsgBuf); jack_error((LPCTSTR)lpDisplayBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); } #else void PrintLoadError(const char* so_name) { jack_log("error loading %s err = %s", so_name, dlerror()); } void BuildClientPath(char* path_to_so, int path_len, const char* so_name) { const char* internal_dir; if ((internal_dir = getenv("JACK_INTERNAL_DIR")) == 0) { if ((internal_dir = getenv("JACK_DRIVER_DIR")) == 0) { internal_dir = ADDON_DIR; } } snprintf(path_to_so, path_len, "%s/%s.so", internal_dir, so_name); } #endif } // end of namespace 1.9.12~dfsg/common/JackException.h0000644000000000000000000000533313214314510015534 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackException__ #define __JackException__ #include "JackCompilerDeps.h" #include #include #include namespace Jack { #define ThrowIf(inCondition, inException) \ if(inCondition) \ { \ throw(inException); \ } /*! \brief Exception base class. */ class SERVER_EXPORT JackException : public std::runtime_error { public: JackException(const std::string& msg) : std::runtime_error(msg) {} JackException(char* msg) : std::runtime_error(msg) {} JackException(const char* msg) : std::runtime_error(msg) {} std::string Message() { return what(); } void PrintMessage(); }; /*! \brief Exception thrown by JackEngine in temporary mode. */ class SERVER_EXPORT JackTemporaryException : public JackException { public: JackTemporaryException(const std::string& msg) : JackException(msg) {} JackTemporaryException(char* msg) : JackException(msg) {} JackTemporaryException(const char* msg) : JackException(msg) {} JackTemporaryException() : JackException("") {} }; /*! \brief */ class SERVER_EXPORT JackQuitException : public JackException { public: JackQuitException(const std::string& msg) : JackException(msg) {} JackQuitException(char* msg) : JackException(msg) {} JackQuitException(const char* msg) : JackException(msg) {} JackQuitException() : JackException("") {} }; /*! \brief Exception possibly thrown by Net slaves. */ class SERVER_EXPORT JackNetException : public JackException { public: JackNetException(const std::string& msg) : JackException(msg) {} JackNetException(char* msg) : JackException(msg) {} JackNetException(const char* msg) : JackException(msg) {} JackNetException() : JackException("") {} }; } #endif 1.9.12~dfsg/common/JackLibClient.h0000644000000000000000000000325513214314510015444 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackLibClient__ #define __JackLibClient__ #include "JackClient.h" #include "JackShmMem.h" #include "JackClientControl.h" #include "JackEngineControl.h" namespace Jack { /*! \brief Client on the library side. */ class JackLibClient : public JackClient { private: JackShmReadWritePtr1 fClientControl; /*! Shared client control */ public: JackLibClient(JackSynchro* table); virtual ~JackLibClient(); int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); void ShutDown(jack_status_t code, const char* message); int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); JackGraphManager* GetGraphManager() const; JackEngineControl* GetEngineControl() const; JackClientControl* GetClientControl() const; }; } // end of namespace #endif 1.9.12~dfsg/common/JackInternalSessionLoader.h0000644000000000000000000000232413214314510020042 0ustar rootroot/* Copyright (C) 2017 Timo Wischer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackInternalSessionLoader__ #define __JackInternalSessionLoader__ #include #include #include "JackServer.h" namespace Jack { class JackInternalSessionLoader { public: JackInternalSessionLoader(JackServer* const server); int Load(const char* file); private: void LoadClient(std::istringstream& iss, const int linenr); void ConnectPorts(std::istringstream& iss, const int linenr); JackServer* const fServer; }; } // end of namespace #endif 1.9.12~dfsg/common/JackProfiler.h0000644000000000000000000000350713214314510015361 0ustar rootroot/* Copyright (C) 2009 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackProfiler__ #define __JackProfiler__ #include "JackConstants.h" #include "JackPlatformPlug.h" #include "jack.h" #include "jslist.h" #include #include #ifdef JACK_MONITOR #include "JackEngineProfiling.h" #endif namespace Jack { struct JackProfilerClient { int fRefNum; jack_client_t* fClient; jack_port_t* fSchedulingPort; jack_port_t* fDurationPort; JackProfilerClient(jack_client_t* client, const char* name); ~JackProfilerClient(); }; /*! \brief Server real-time monitoring */ class JackProfiler { private: jack_client_t* fClient; jack_port_t* fCPULoadPort; jack_port_t* fDriverPeriodPort; jack_port_t* fDriverEndPort; #ifdef JACK_MONITOR JackTimingMeasure* fLastMeasure; std::map fClientTable; JackMutex fMutex; #endif public: JackProfiler(jack_client_t* jack_client, const JSList* params); ~JackProfiler(); static int Process(jack_nframes_t nframes, void* arg); static void ClientRegistration(const char* name, int val, void *arg); }; } #endif 1.9.12~dfsg/common/JackNetAdapter.h0000644000000000000000000000364213214314510015626 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackNetAdapter__ #define __JackNetAdapter__ #include "JackAudioAdapterInterface.h" #include "JackNetInterface.h" namespace Jack { /*! \brief Net adapter. */ class JackNetAdapter : public JackAudioAdapterInterface, public JackNetSlaveInterface, public JackRunnableInterface { private: //jack data jack_client_t* fClient; //transport data int fLastTransportState; int fLastTimebaseMaster; //sample buffers sample_t** fSoftCaptureBuffer; sample_t** fSoftPlaybackBuffer; //adapter thread JackThread fThread; //transport void EncodeTransportData(); void DecodeTransportData(); public: JackNetAdapter(jack_client_t* jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackNetAdapter(); int Open(); int Close(); int SetBufferSize(jack_nframes_t buffer_size); bool Init(); bool Execute(); int Read(); int Write(); int Process(); }; } #endif 1.9.12~dfsg/common/JackTimedDriver.cpp0000644000000000000000000000526313214314510016351 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackTimedDriver.h" #include "JackEngineControl.h" #include "JackTime.h" #include "JackCompilerDeps.h" #include #include #include namespace Jack { int JackTimedDriver::FirstCycle(jack_time_t cur_time_usec) { fAnchorTimeUsec = cur_time_usec; return int((double(fEngineControl->fBufferSize) * 1000000) / double(fEngineControl->fSampleRate)); } int JackTimedDriver::CurrentCycle(jack_time_t cur_time_usec) { return int(((double(fCycleCount) * double(fEngineControl->fBufferSize) * 1000000.) / double(fEngineControl->fSampleRate)) - (cur_time_usec - fAnchorTimeUsec)); } int JackTimedDriver::Start() { fCycleCount = 0; return JackAudioDriver::Start(); } void JackTimedDriver::ProcessWait() { jack_time_t cur_time_usec = GetMicroSeconds(); int wait_time_usec; if (fCycleCount++ == 0) { wait_time_usec = FirstCycle(cur_time_usec); } else { wait_time_usec = CurrentCycle(cur_time_usec); } if (wait_time_usec < 0) { NotifyXRun(cur_time_usec, float(cur_time_usec - fBeginDateUst)); fCycleCount = 0; wait_time_usec = 0; jack_error("JackTimedDriver::Process XRun = %ld usec", (cur_time_usec - fBeginDateUst)); } //jack_log("JackTimedDriver::Process wait_time = %d", wait_time_usec); JackSleep(wait_time_usec); } int JackWaiterDriver::ProcessNull() { JackDriver::CycleTakeBeginTime(); // Graph processing without Read/Write if (fEngineControl->fSyncMode) { ProcessGraphSync(); } else { ProcessGraphAsync(); } // Keep end cycle time JackDriver::CycleTakeEndTime(); ProcessWait(); return 0; } void JackRestarterDriver::SetRestartDriver(JackDriver* driver) { fRestartDriver = driver; } int JackRestarterDriver::RestartWait() { if (!fRestartDriver) { jack_error("JackRestartedDriver::RestartWait driver not set"); return -1; } return fRestartDriver->Start(); } } // end of namespace 1.9.12~dfsg/common/JackMidiAsyncWaitQueue.h0000644000000000000000000000574713214314510017321 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiAsyncWaitQueue__ #define __JackMidiAsyncWaitQueue__ #include "JackMidiAsyncQueue.h" namespace Jack { /** * This is an asynchronous wait queue that allows a thread to wait for a * message, either indefinitely or for a specified time. This is one * example of a way that the `JackMidiAsyncQueue` class can be extended so * that process threads can interact with non-process threads to send MIDI * events. * * XXX: As of right now, this code hasn't been tested. Also, note the * warning in the JackMidiAsyncWaitQueue.cpp about semaphore wait * resolution. */ class SERVER_EXPORT JackMidiAsyncWaitQueue: public JackMidiAsyncQueue { private: JackSynchro semaphore; public: using JackMidiAsyncQueue::EnqueueEvent; /** * Creates a new asynchronous MIDI wait message queue. The queue can * store up to `max_messages` MIDI messages and up to `max_bytes` of * MIDI data before it starts rejecting messages. */ JackMidiAsyncWaitQueue(size_t max_bytes=4096, size_t max_messages=1024); ~JackMidiAsyncWaitQueue(); /** * Dequeues and returns a MIDI event. Returns '0' if there are no MIDI * events available right now. */ jack_midi_event_t * DequeueEvent(); /** * Waits a specified time for a MIDI event to be available, or * indefinitely if the time is negative. Returns the MIDI event, or * '0' if time runs out and no MIDI event is available. */ jack_midi_event_t * DequeueEvent(long usecs); /** * Waits until the specified frame for a MIDI event to be available. * Returns the MIDI event, or '0' if time runs out and no MIDI event is * available. */ jack_midi_event_t * DequeueEvent(jack_nframes_t frame); /** * Enqueues the MIDI event specified by the arguments. The return * value indiciates whether or not the event was successfully enqueued. */ EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); }; } #endif 1.9.12~dfsg/common/JackTime.h0000644000000000000000000000231213214314510014466 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackTime__ #define __JackTime__ #include "JackCompilerDeps.h" #include "JackTypes.h" #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT void InitTime(); SERVER_EXPORT void EndTime(); SERVER_EXPORT jack_time_t GetMicroSeconds(void); SERVER_EXPORT void JackSleep(long usec); void SetClockSource(jack_timer_type_t source); const char* ClockSourceName(jack_timer_type_t source); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/common/JackMidiReceiveQueue.cpp0000644000000000000000000000155413214314510017324 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMidiReceiveQueue.h" using Jack::JackMidiReceiveQueue; JackMidiReceiveQueue::~JackMidiReceiveQueue() { // Empty } 1.9.12~dfsg/common/JackNetManager.h0000644000000000000000000001063013214314510015613 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JACKNETMANAGER_H__ #define __JACKNETMANAGER_H__ #include "JackNetInterface.h" #include "jack.h" #include #include namespace Jack { class JackNetMasterManager; /** \Brief This class describes a Net Master */ typedef std::list > connections_list_t; class JackNetMaster : public JackNetMasterInterface { friend class JackNetMasterManager; private: static int SetProcess(jack_nframes_t nframes, void* arg); static int SetBufferSize(jack_nframes_t nframes, void* arg); static int SetSampleRate(jack_nframes_t nframes, void* arg); static void SetTimebaseCallback(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg); static void SetConnectCallback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg); static void LatencyCallback(jack_latency_callback_mode_t mode, void* arg); //jack client jack_client_t* fClient; const char* fName; //jack ports jack_port_t** fAudioCapturePorts; jack_port_t** fAudioPlaybackPorts; jack_port_t** fMidiCapturePorts; jack_port_t** fMidiPlaybackPorts; //sync and transport int fLastTransportState; //monitoring #ifdef JACK_MONITOR jack_time_t fPeriodUsecs; JackGnuPlotMonitor* fNetTimeMon; #endif bool Init(bool auto_connect); int AllocPorts(); void FreePorts(); //transport void EncodeTransportData(); void DecodeTransportData(); int Process(); void TimebaseCallback(jack_position_t* pos); void ConnectPorts(); void ConnectCallback(jack_port_id_t a, jack_port_id_t b, int connect); void SaveConnections(connections_list_t& connections); void LoadConnections(const connections_list_t& connections); public: JackNetMaster(JackNetSocket& socket, session_params_t& params, const char* multicast_ip); ~JackNetMaster(); bool IsSlaveReadyToRoll(); }; typedef std::list master_list_t; typedef master_list_t::iterator master_list_it_t; typedef std::map master_connections_list_t; /** \Brief This class describer the Network Manager */ class JackNetMasterManager { friend class JackNetMaster; private: static void SetShutDown(void* arg); static int SetSyncCallback(jack_transport_state_t state, jack_position_t* pos, void* arg); static void* NetManagerThread(void* arg); jack_client_t* fClient; const char* fName; char fMulticastIP[32]; JackNetSocket fSocket; jack_native_thread_t fThread; master_list_t fMasterList; master_connections_list_t fMasterConnectionList; uint32_t fGlobalID; bool fRunning; bool fAutoConnect; bool fAutoSave; void Run(); JackNetMaster* InitMaster(session_params_t& params); master_list_it_t FindMaster(uint32_t client_id); int KillMaster(session_params_t* params); int SyncCallback(jack_transport_state_t state, jack_position_t* pos); int CountIO(const char* type, int flags); void ShutDown(); public: JackNetMasterManager(jack_client_t* jack_client, const JSList* params); ~JackNetMasterManager(); }; } #endif 1.9.12~dfsg/common/JackLockedEngine.h0000644000000000000000000003064713214314510016133 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackLockedEngine__ #define __JackLockedEngine__ #include "JackEngine.h" #include "JackMutex.h" #include "JackTools.h" #include "JackException.h" namespace Jack { #define TRY_CALL \ try { \ /* See : http://groups.google.com/group/comp.programming.threads/browse_thread/thread/652bcf186fbbf697/f63757846514e5e5 catch (...) { // Assuming thread cancellation, must rethrow throw; } */ #define CATCH_EXCEPTION_RETURN \ } catch (std::bad_alloc& e) { \ jack_error("Memory allocation error..."); \ return -1; \ } catch (...) { \ jack_error("Unknown error..."); \ throw; \ } \ #define CATCH_CLOSE_EXCEPTION_RETURN \ } catch (std::bad_alloc& e) { \ jack_error("Memory allocation error..."); \ return -1; \ } catch (JackTemporaryException& e) { \ jack_error("JackTemporaryException : now quits..."); \ JackTools::KillServer(); \ return 0; \ } catch (...) { \ jack_error("Unknown error..."); \ throw; \ } #define CATCH_EXCEPTION \ } catch (std::bad_alloc& e) { \ jack_error("Memory allocation error..."); \ } catch (...) { \ jack_error("Unknown error..."); \ throw; \ } \ /*! \brief Locked Engine, access to methods is serialized using a mutex. */ class SERVER_EXPORT JackLockedEngine { private: JackEngine fEngine; public: JackLockedEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler, char self_connect_mode): fEngine(manager, table, controler, self_connect_mode) {} ~JackLockedEngine() {} bool Lock() { return fEngine.Lock(); } bool Unlock() { return fEngine.Unlock(); } bool Trylock() { return fEngine.Trylock(); } int Open() { // No lock needed TRY_CALL return fEngine.Open(); CATCH_EXCEPTION_RETURN } int Close() { // No lock needed TRY_CALL return fEngine.Close(); CATCH_EXCEPTION_RETURN } // Client management int ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status) { TRY_CALL JackLock lock(&fEngine); return fEngine.ClientCheck(name, uuid, name_res, protocol, options, status); CATCH_EXCEPTION_RETURN } int ClientExternalOpen(const char* name, int pid, int uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { TRY_CALL JackLock lock(&fEngine); return fEngine.ClientExternalOpen(name, pid, uuid, ref, shared_engine, shared_client, shared_graph_manager); CATCH_EXCEPTION_RETURN } int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) { TRY_CALL JackLock lock(&fEngine); return fEngine.ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait); CATCH_EXCEPTION_RETURN } int ClientExternalClose(int refnum) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.ClientExternalClose(refnum) : -1; CATCH_CLOSE_EXCEPTION_RETURN } int ClientInternalClose(int refnum, bool wait) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.ClientInternalClose(refnum, wait) : -1; CATCH_CLOSE_EXCEPTION_RETURN } int ClientActivate(int refnum, bool is_real_time) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.ClientActivate(refnum, is_real_time) : -1; CATCH_EXCEPTION_RETURN } int ClientDeactivate(int refnum) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum) : -1; CATCH_EXCEPTION_RETURN } void ClientKill(int refnum) { TRY_CALL JackLock lock(&fEngine); fEngine.ClientKill(refnum); CATCH_EXCEPTION } // Internal client management int GetInternalClientName(int int_ref, char* name_res) { TRY_CALL JackLock lock(&fEngine); return fEngine.GetInternalClientName(int_ref, name_res); CATCH_EXCEPTION_RETURN } int InternalClientHandle(const char* client_name, int* status, int* int_ref) { TRY_CALL JackLock lock(&fEngine); return fEngine.InternalClientHandle(client_name, status, int_ref); CATCH_EXCEPTION_RETURN } int InternalClientUnload(int refnum, int* status) { TRY_CALL JackLock lock(&fEngine); // Client is tested in fEngine.InternalClientUnload return fEngine.InternalClientUnload(refnum, status); CATCH_EXCEPTION_RETURN } // Port management int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.PortRegister(refnum, name, type, flags, buffer_size, port) : -1; CATCH_EXCEPTION_RETURN } int PortUnRegister(int refnum, jack_port_id_t port) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.PortUnRegister(refnum, port) : -1; CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, const char* src, const char* dst) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1; CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, const char* src, const char* dst) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1; CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1; CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1; CATCH_EXCEPTION_RETURN } int PortRename(int refnum, jack_port_id_t port, const char* name) { TRY_CALL JackLock lock(&fEngine); return (fEngine.CheckClient(refnum)) ? fEngine.PortRename(refnum, port, name) : -1; CATCH_EXCEPTION_RETURN } int ComputeTotalLatencies() { TRY_CALL JackLock lock(&fEngine); return fEngine.ComputeTotalLatencies(); CATCH_EXCEPTION_RETURN } // Graph bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { // RT : no lock return fEngine.Process(cur_cycle_begin, prev_cycle_end); } // Notifications void NotifyDriverXRun() { // Coming from the driver in RT : no lock fEngine.NotifyDriverXRun(); } void NotifyClientXRun(int refnum) { TRY_CALL JackLock lock(&fEngine); fEngine.NotifyClientXRun(refnum); CATCH_EXCEPTION } void NotifyGraphReorder() { TRY_CALL JackLock lock(&fEngine); fEngine.NotifyGraphReorder(); CATCH_EXCEPTION } void NotifyBufferSize(jack_nframes_t buffer_size) { TRY_CALL JackLock lock(&fEngine); fEngine.NotifyBufferSize(buffer_size); CATCH_EXCEPTION } void NotifySampleRate(jack_nframes_t sample_rate) { TRY_CALL JackLock lock(&fEngine); fEngine.NotifySampleRate(sample_rate); CATCH_EXCEPTION } void NotifyFreewheel(bool onoff) { TRY_CALL JackLock lock(&fEngine); fEngine.NotifyFreewheel(onoff); CATCH_EXCEPTION } void NotifyFailure(int code, const char* reason) { TRY_CALL JackLock lock(&fEngine); fEngine.NotifyFailure(code, reason); CATCH_EXCEPTION } int GetClientPID(const char* name) { TRY_CALL JackLock lock(&fEngine); return fEngine.GetClientPID(name); CATCH_EXCEPTION_RETURN } int GetClientRefNum(const char* name) { TRY_CALL JackLock lock(&fEngine); return fEngine.GetClientRefNum(name); CATCH_EXCEPTION_RETURN } void NotifyQuit() { // No lock needed TRY_CALL return fEngine.NotifyQuit(); CATCH_EXCEPTION } void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, detail::JackChannelTransactionInterface *socket, JackSessionNotifyResult** result) { TRY_CALL JackLock lock(&fEngine); fEngine.SessionNotify(refnum, target, type, path, socket, result); CATCH_EXCEPTION } int SessionReply(int refnum) { TRY_CALL JackLock lock(&fEngine); return fEngine.SessionReply(refnum); CATCH_EXCEPTION_RETURN } int GetUUIDForClientName(const char *client_name, char *uuid_res) { TRY_CALL JackLock lock(&fEngine); return fEngine.GetUUIDForClientName(client_name, uuid_res); CATCH_EXCEPTION_RETURN } int GetClientNameForUUID(const char *uuid, char *name_res) { TRY_CALL JackLock lock(&fEngine); return fEngine.GetClientNameForUUID(uuid, name_res); CATCH_EXCEPTION_RETURN } int ReserveClientName(const char *name, const char *uuid) { TRY_CALL JackLock lock(&fEngine); return fEngine.ReserveClientName(name, uuid); CATCH_EXCEPTION_RETURN } int ClientHasSessionCallback(const char *name) { TRY_CALL JackLock lock(&fEngine); return fEngine.ClientHasSessionCallback(name); CATCH_EXCEPTION_RETURN } }; } // end of namespace #endif 1.9.12~dfsg/common/memops.c0000644000000000000000000010050313214314510014273 0ustar rootroot/* Copyright (C) 2000 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 #define __USE_ISOC9X 1 #define __USE_ISOC99 1 #include #include #include #include #include #include #include #ifdef __linux__ #include #endif #include "memops.h" #if defined (__SSE2__) && !defined (__sun__) #include #ifdef __SSE4_1__ #include #endif #endif #ifdef __ARM_NEON__ #include #endif /* Notes about these *_SCALING values. the MAX_BIT values are floating point. when multiplied by a full-scale normalized floating point sample value (-1.0..+1.0) they should give the maxium value representable with an integer sample type of N bits. Note that this is asymmetric. Sample ranges for signed integer, 2's complement values are -(2^(N-1) to +(2^(N-1)-1) Complications ------------- If we use +2^(N-1) for the scaling factors, we run into a problem: if we start with a normalized float value of -1.0, scaling to 24 bits would give -8388608 (-2^23), which is ideal. But with +1.0, we get +8388608, which is technically out of range. We never multiply a full range normalized value by this constant, but we could multiply it by a positive value that is close enough to +1.0 to produce a value > +(2^(N-1)-1. There is no way around this paradox without wasting CPU cycles to determine which scaling factor to use (i.e. determine if its negative or not, use the right factor). So, for now (October 2008) we use 2^(N-1)-1 as the scaling factor. */ #define SAMPLE_24BIT_SCALING 8388607.0f #define SAMPLE_16BIT_SCALING 32767.0f /* these are just values to use if the floating point value was out of range advice from Fons Adriaensen: make the limits symmetrical */ #define SAMPLE_24BIT_MAX 8388607 #define SAMPLE_24BIT_MIN -8388607 #define SAMPLE_24BIT_MAX_F 8388607.0f #define SAMPLE_24BIT_MIN_F -8388607.0f #define SAMPLE_16BIT_MAX 32767 #define SAMPLE_16BIT_MIN -32767 #define SAMPLE_16BIT_MAX_F 32767.0f #define SAMPLE_16BIT_MIN_F -32767.0f /* these mark the outer edges of the range considered "within" range for a floating point sample value. values outside (and on the boundaries) of this range will be clipped before conversion; values within this range will be scaled to appropriate values for the target sample type. */ #define NORMALIZED_FLOAT_MIN -1.0f #define NORMALIZED_FLOAT_MAX 1.0f /* define this in case we end up on a platform that is missing the real lrintf functions */ #define f_round(f) lrintf(f) #define float_16(s, d)\ if ((s) <= NORMALIZED_FLOAT_MIN) {\ (d) = SAMPLE_16BIT_MIN;\ } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ (d) = SAMPLE_16BIT_MAX;\ } else {\ (d) = f_round ((s) * SAMPLE_16BIT_SCALING);\ } /* call this when "s" has already been scaled (e.g. when dithering) */ #define float_16_scaled(s, d)\ if ((s) <= SAMPLE_16BIT_MIN_F) {\ (d) = SAMPLE_16BIT_MIN_F;\ } else if ((s) >= SAMPLE_16BIT_MAX_F) { \ (d) = SAMPLE_16BIT_MAX;\ } else {\ (d) = f_round ((s));\ } #define float_24u32(s, d) \ if ((s) <= NORMALIZED_FLOAT_MIN) {\ (d) = SAMPLE_24BIT_MIN << 8;\ } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ (d) = SAMPLE_24BIT_MAX << 8;\ } else {\ (d) = f_round ((s) * SAMPLE_24BIT_SCALING) << 8;\ } /* call this when "s" has already been scaled (e.g. when dithering) */ #define float_24u32_scaled(s, d)\ if ((s) <= SAMPLE_24BIT_MIN_F) {\ (d) = SAMPLE_24BIT_MIN << 8;\ } else if ((s) >= SAMPLE_24BIT_MAX_F) { \ (d) = SAMPLE_24BIT_MAX << 8; \ } else {\ (d) = f_round ((s)) << 8; \ } #define float_24(s, d) \ if ((s) <= NORMALIZED_FLOAT_MIN) {\ (d) = SAMPLE_24BIT_MIN;\ } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ (d) = SAMPLE_24BIT_MAX;\ } else {\ (d) = f_round ((s) * SAMPLE_24BIT_SCALING);\ } /* call this when "s" has already been scaled (e.g. when dithering) */ #define float_24_scaled(s, d)\ if ((s) <= SAMPLE_24BIT_MIN_F) {\ (d) = SAMPLE_24BIT_MIN;\ } else if ((s) >= SAMPLE_24BIT_MAX_F) { \ (d) = SAMPLE_24BIT_MAX; \ } else {\ (d) = f_round ((s)); \ } #if defined (__SSE2__) && !defined (__sun__) /* generates same as _mm_set_ps(1.f, 1.f, 1f., 1f) but faster */ static inline __m128 gen_one(void) { volatile __m128i x = { 0 }; /* shut up, GCC */ __m128i ones = _mm_cmpeq_epi32(x, x); return (__m128)_mm_slli_epi32 (_mm_srli_epi32(ones, 25), 23); } static inline __m128 clip(__m128 s, __m128 min, __m128 max) { return _mm_min_ps(max, _mm_max_ps(s, min)); } static inline __m128i float_24_sse(__m128 s) { const __m128 upper_bound = gen_one(); /* NORMALIZED_FLOAT_MAX */ const __m128 lower_bound = _mm_sub_ps(_mm_setzero_ps(), upper_bound); __m128 clipped = clip(s, lower_bound, upper_bound); __m128 scaled = _mm_mul_ps(clipped, _mm_set1_ps(SAMPLE_24BIT_SCALING)); return _mm_cvtps_epi32(scaled); } #endif #ifdef __ARM_NEON__ static inline float32x4_t clip(float32x4_t s, float32x4_t min, float32x4_t max) { return vminq_f32(max, vmaxq_f32(s, min)); } static inline int32x4_t float_24_neon(float32x4_t s) { const float32x4_t upper_bound = vdupq_n_f32(NORMALIZED_FLOAT_MAX); const float32x4_t lower_bound = vdupq_n_f32(NORMALIZED_FLOAT_MIN); float32x4_t clipped = clip(s, lower_bound, upper_bound); float32x4_t scaled = vmulq_f32(clipped, vdupq_n_f32(SAMPLE_24BIT_SCALING)); return vcvtq_s32_f32(scaled); } static inline int16x4_t float_16_neon(float32x4_t s) { const float32x4_t upper_bound = vdupq_n_f32(NORMALIZED_FLOAT_MAX); const float32x4_t lower_bound = vdupq_n_f32(NORMALIZED_FLOAT_MIN); float32x4_t clipped = clip(s, lower_bound, upper_bound); float32x4_t scaled = vmulq_f32(clipped, vdupq_n_f32(SAMPLE_16BIT_SCALING)); return vmovn_s32(vcvtq_s32_f32(scaled)); } #endif /* Linear Congruential noise generator. From the music-dsp list * less random than rand(), but good enough and 10x faster */ static unsigned int seed = 22222; static inline unsigned int fast_rand() { seed = (seed * 196314165) + 907633515; return seed; } /* functions for native float sample data */ void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { while (nsamples--) { *dst = *((float *) src); dst++; src += src_skip; } } void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { while (nsamples--) { *((float *) dst) = *src; dst += dst_skip; src++; } } /* NOTES on function naming: foo_bar_d_s the "d" component defines the destination type for the operation the "s" component defines the source type for the operation TYPE can be one of: S - sample is a jack_default_audio_sample_t, currently (October 2008) a 32 bit floating point value Ss - like S but reverse endian from the host CPU 32u24 - sample is an signed 32 bit integer value, but data is in upper 24 bits only 32u24s - like 32u24 but reverse endian from the host CPU 24 - sample is an signed 24 bit integer value 24s - like 24 but reverse endian from the host CPU 16 - sample is an signed 16 bit integer value 16s - like 16 but reverse endian from the host CPU For obvious reasons, the reverse endian versions only show as source types. This covers all known sample formats at 16 bits or larger. */ /* functions for native integer sample data */ void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { #ifdef __ARM_NEON__ unsigned long unrolled = nsamples / 4; nsamples = nsamples & 3; while (unrolled--) { float32x4_t samples = vld1q_f32(src); int32x4_t converted = float_24_neon(samples); int32x4_t shifted = vshlq_n_s32(converted, 8); shifted = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(shifted))); switch(dst_skip) { case 4: vst1q_s32((int32_t*)dst, shifted); break; default: vst1q_lane_s32((int32_t*)(dst), shifted, 0); vst1q_lane_s32((int32_t*)(dst+dst_skip), shifted, 1); vst1q_lane_s32((int32_t*)(dst+2*dst_skip), shifted, 2); vst1q_lane_s32((int32_t*)(dst+3*dst_skip), shifted, 3); break; } dst += 4*dst_skip; src+= 4; } #endif int32_t z; while (nsamples--) { float_24u32 (*src, z); #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(z>>24); dst[1]=(char)(z>>16); dst[2]=(char)(z>>8); dst[3]=(char)(z); #elif __BYTE_ORDER == __BIG_ENDIAN dst[0]=(char)(z); dst[1]=(char)(z>>8); dst[2]=(char)(z>>16); dst[3]=(char)(z>>24); #endif dst += dst_skip; src++; } } void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { #if defined (__SSE2__) && !defined (__sun__) __m128 int_max = _mm_set1_ps(SAMPLE_24BIT_MAX_F); __m128 int_min = _mm_sub_ps(_mm_setzero_ps(), int_max); __m128 factor = int_max; unsigned long unrolled = nsamples / 4; nsamples = nsamples & 3; while (unrolled--) { __m128 in = _mm_load_ps(src); __m128 scaled = _mm_mul_ps(in, factor); __m128 clipped = clip(scaled, int_min, int_max); __m128i y = _mm_cvttps_epi32(clipped); __m128i shifted = _mm_slli_epi32(y, 8); #ifdef __SSE4_1__ *(int32_t*)dst = _mm_extract_epi32(shifted, 0); *(int32_t*)(dst+dst_skip) = _mm_extract_epi32(shifted, 1); *(int32_t*)(dst+2*dst_skip) = _mm_extract_epi32(shifted, 2); *(int32_t*)(dst+3*dst_skip) = _mm_extract_epi32(shifted, 3); #else __m128i shuffled1 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(0, 3, 2, 1)); __m128i shuffled2 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(1, 0, 3, 2)); __m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3)); _mm_store_ss((float*)dst, (__m128)shifted); _mm_store_ss((float*)(dst+dst_skip), (__m128)shuffled1); _mm_store_ss((float*)(dst+2*dst_skip), (__m128)shuffled2); _mm_store_ss((float*)(dst+3*dst_skip), (__m128)shuffled3); #endif dst += 4*dst_skip; src+= 4; } while (nsamples--) { __m128 in = _mm_load_ss(src); __m128 scaled = _mm_mul_ss(in, factor); __m128 clipped = _mm_min_ss(int_max, _mm_max_ss(scaled, int_min)); int y = _mm_cvttss_si32(clipped); *((int *) dst) = y<<8; dst += dst_skip; src++; } #elif defined(__ARM_NEON__) unsigned long unrolled = nsamples / 4; nsamples = nsamples & 3; while (unrolled--) { float32x4_t samples = vld1q_f32(src); int32x4_t converted = float_24_neon(samples); int32x4_t shifted = vshlq_n_s32(converted, 8); switch(dst_skip) { case 4: vst1q_s32((int32_t*)dst, shifted); break; default: vst1q_lane_s32((int32_t*)(dst), shifted, 0); vst1q_lane_s32((int32_t*)(dst+dst_skip), shifted, 1); vst1q_lane_s32((int32_t*)(dst+2*dst_skip), shifted, 2); vst1q_lane_s32((int32_t*)(dst+3*dst_skip), shifted, 3); break; } dst += 4*dst_skip; src+= 4; } #endif #if !defined (__SSE2__) while (nsamples--) { float_24u32 (*src, *((int32_t*) dst)); dst += dst_skip; src++; } #endif } void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { #ifdef __ARM_NEON__ float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING); unsigned long unrolled = nsamples / 4; while (unrolled--) { int32x4_t src128; switch(src_skip) { case 4: src128 = vld1q_s32((int32_t*)src); break; case 8: src128 = vld2q_s32((int32_t*)src).val[0]; break; default: src128 = vld1q_lane_s32((int32_t*)src, src128, 0); src128 = vld1q_lane_s32((int32_t*)(src+src_skip), src128, 1); src128 = vld1q_lane_s32((int32_t*)(src+2*src_skip), src128, 2); src128 = vld1q_lane_s32((int32_t*)(src+3*src_skip), src128, 3); break; } src128 = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(src128))); int32x4_t shifted = vshrq_n_s32(src128, 8); float32x4_t as_float = vcvtq_f32_s32(shifted); float32x4_t divided = vmulq_f32(as_float, factor); vst1q_f32(dst, divided); src += 4*src_skip; dst += 4; } nsamples = nsamples & 3; #endif /* ALERT: signed sign-extension portability !!! */ const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; while (nsamples--) { int x; #if __BYTE_ORDER == __LITTLE_ENDIAN x = (unsigned char)(src[0]); x <<= 8; x |= (unsigned char)(src[1]); x <<= 8; x |= (unsigned char)(src[2]); x <<= 8; x |= (unsigned char)(src[3]); #elif __BYTE_ORDER == __BIG_ENDIAN x = (unsigned char)(src[3]); x <<= 8; x |= (unsigned char)(src[2]); x <<= 8; x |= (unsigned char)(src[1]); x <<= 8; x |= (unsigned char)(src[0]); #endif *dst = (x >> 8) * scaling; dst++; src += src_skip; } } void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { #if defined (__SSE2__) && !defined (__sun__) unsigned long unrolled = nsamples / 4; static float inv_sample_max_24bit = 1.0 / SAMPLE_24BIT_SCALING; __m128 factor = _mm_set1_ps(inv_sample_max_24bit); while (unrolled--) { int i1 = *((int *) src); src+= src_skip; int i2 = *((int *) src); src+= src_skip; int i3 = *((int *) src); src+= src_skip; int i4 = *((int *) src); src+= src_skip; __m128i src = _mm_set_epi32(i4, i3, i2, i1); __m128i shifted = _mm_srai_epi32(src, 8); __m128 as_float = _mm_cvtepi32_ps(shifted); __m128 divided = _mm_mul_ps(as_float, factor); _mm_storeu_ps(dst, divided); dst += 4; } nsamples = nsamples & 3; #elif defined(__ARM_NEON__) unsigned long unrolled = nsamples / 4; float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING); while (unrolled--) { int32x4_t src128; switch(src_skip) { case 4: src128 = vld1q_s32((int32_t*)src); break; case 8: src128 = vld2q_s32((int32_t*)src).val[0]; break; default: src128 = vld1q_lane_s32((int32_t*)src, src128, 0); src128 = vld1q_lane_s32((int32_t*)(src+src_skip), src128, 1); src128 = vld1q_lane_s32((int32_t*)(src+2*src_skip), src128, 2); src128 = vld1q_lane_s32((int32_t*)(src+3*src_skip), src128, 3); break; } int32x4_t shifted = vshrq_n_s32(src128, 8); float32x4_t as_float = vcvtq_f32_s32(shifted); float32x4_t divided = vmulq_f32(as_float, factor); vst1q_f32(dst, divided); src += 4*src_skip; dst += 4; } nsamples = nsamples & 3; #endif /* ALERT: signed sign-extension portability !!! */ const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; while (nsamples--) { *dst = (*((int *) src) >> 8) * scaling; dst++; src += src_skip; } } void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { #ifdef __ARM_NEON__ unsigned long unrolled = nsamples / 4; while (unrolled--) { int i; int32_t z[4]; float32x4_t samples = vld1q_f32(src); int32x4_t converted = float_24_neon(samples); converted = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(converted))); vst1q_s32(z, converted); for (i = 0; i != 4; ++i) { memcpy (dst, ((char*)(z+i))+1, 3); dst += dst_skip; } src += 4; } nsamples = nsamples & 3; #endif int32_t z; while (nsamples--) { float_24 (*src, z); #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(z>>16); dst[1]=(char)(z>>8); dst[2]=(char)(z); #elif __BYTE_ORDER == __BIG_ENDIAN dst[0]=(char)(z); dst[1]=(char)(z>>8); dst[2]=(char)(z>>16); #endif dst += dst_skip; src++; } } void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { #if defined (__SSE2__) && !defined (__sun__) _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); while (nsamples >= 4) { int i; int32_t z[4]; __m128 samples = _mm_loadu_ps(src); __m128i converted = float_24_sse(samples); #ifdef __SSE4_1__ z[0] = _mm_extract_epi32(converted, 0); z[1] = _mm_extract_epi32(converted, 1); z[2] = _mm_extract_epi32(converted, 2); z[3] = _mm_extract_epi32(converted, 3); #else __m128i shuffled1 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(0, 3, 2, 1)); __m128i shuffled2 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(1, 0, 3, 2)); __m128i shuffled3 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(2, 1, 0, 3)); _mm_store_ss((float*)z, (__m128)converted); _mm_store_ss((float*)z+1, (__m128)shuffled1); _mm_store_ss((float*)z+2, (__m128)shuffled2); _mm_store_ss((float*)z+3, (__m128)shuffled3); #endif for (i = 0; i != 4; ++i) { memcpy (dst, z+i, 3); dst += dst_skip; } nsamples -= 4; src += 4; } #elif defined(__ARM_NEON__) unsigned long unrolled = nsamples / 4; while (unrolled--) { int i; int32_t z[4]; float32x4_t samples = vld1q_f32(src); int32x4_t converted = float_24_neon(samples); vst1q_s32(z, converted); for (i = 0; i != 4; ++i) { memcpy (dst, z+i, 3); dst += dst_skip; } src += 4; } nsamples = nsamples & 3; #endif int32_t z; while (nsamples--) { float_24 (*src, z); #if __BYTE_ORDER == __LITTLE_ENDIAN memcpy (dst, &z, 3); #elif __BYTE_ORDER == __BIG_ENDIAN memcpy (dst, (char *)&z + 1, 3); #endif dst += dst_skip; src++; } } void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; #ifdef __ARM_NEON__ // we shift 8 to the right by dividing by 256.0 -> no sign extra handling const float32x4_t vscaling = vdupq_n_f32(scaling/256.0); int32_t x[4]; memset(x, 0, sizeof(x)); unsigned long unrolled = nsamples / 4; while (unrolled--) { #if __BYTE_ORDER == __BIG_ENDIAN /* ARM big endian?? */ // right aligned / inverse sequence below -> *256 memcpy(((char*)&x[0])+1, src, 3); memcpy(((char*)&x[1])+1, src+src_skip, 3); memcpy(((char*)&x[2])+1, src+2*src_skip, 3); memcpy(((char*)&x[3])+1, src+3*src_skip, 3); #else memcpy(&x[0], src, 3); memcpy(&x[1], src+src_skip, 3); memcpy(&x[2], src+2*src_skip, 3); memcpy(&x[3], src+3*src_skip, 3); #endif src += 4 * src_skip; int32x4_t source = vld1q_s32(x); source = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(source))); float32x4_t converted = vcvtq_f32_s32(source); float32x4_t scaled = vmulq_f32(converted, vscaling); vst1q_f32(dst, scaled); dst += 4; } nsamples = nsamples & 3; #endif /* ALERT: signed sign-extension portability !!! */ while (nsamples--) { int x; #if __BYTE_ORDER == __LITTLE_ENDIAN x = (unsigned char)(src[0]); x <<= 8; x |= (unsigned char)(src[1]); x <<= 8; x |= (unsigned char)(src[2]); /* correct sign bit and the rest of the top byte */ if (src[0] & 0x80) { x |= 0xff << 24; } #elif __BYTE_ORDER == __BIG_ENDIAN x = (unsigned char)(src[2]); x <<= 8; x |= (unsigned char)(src[1]); x <<= 8; x |= (unsigned char)(src[0]); /* correct sign bit and the rest of the top byte */ if (src[2] & 0x80) { x |= 0xff << 24; } #endif *dst = x * scaling; dst++; src += src_skip; } } void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { const jack_default_audio_sample_t scaling = 1.f/SAMPLE_24BIT_SCALING; #if defined (__SSE2__) && !defined (__sun__) const __m128 scaling_block = _mm_set_ps1(scaling); while (nsamples >= 4) { int x0, x1, x2, x3; memcpy((char*)&x0 + 1, src, 3); memcpy((char*)&x1 + 1, src+src_skip, 3); memcpy((char*)&x2 + 1, src+2*src_skip, 3); memcpy((char*)&x3 + 1, src+3*src_skip, 3); src += 4 * src_skip; const __m128i block_i = _mm_set_epi32(x3, x2, x1, x0); const __m128i shifted = _mm_srai_epi32(block_i, 8); const __m128 converted = _mm_cvtepi32_ps (shifted); const __m128 scaled = _mm_mul_ps(converted, scaling_block); _mm_storeu_ps(dst, scaled); dst += 4; nsamples -= 4; } #elif defined(__ARM_NEON__) // we shift 8 to the right by dividing by 256.0 -> no sign extra handling const float32x4_t vscaling = vdupq_n_f32(scaling/256.0); int32_t x[4]; memset(x, 0, sizeof(x)); unsigned long unrolled = nsamples / 4; while (unrolled--) { #if __BYTE_ORDER == __BIG_ENDIAN /* ARM big endian?? */ // left aligned -> *256 memcpy(&x[0], src, 3); memcpy(&x[1], src+src_skip, 3); memcpy(&x[2], src+2*src_skip, 3); memcpy(&x[3], src+3*src_skip, 3); #else memcpy(((char*)&x[0])+1, src, 3); memcpy(((char*)&x[1])+1, src+src_skip, 3); memcpy(((char*)&x[2])+1, src+2*src_skip, 3); memcpy(((char*)&x[3])+1, src+3*src_skip, 3); #endif src += 4 * src_skip; int32x4_t source = vld1q_s32(x); float32x4_t converted = vcvtq_f32_s32(source); float32x4_t scaled = vmulq_f32(converted, vscaling); vst1q_f32(dst, scaled); dst += 4; } nsamples = nsamples & 3; #endif while (nsamples--) { int x; #if __BYTE_ORDER == __LITTLE_ENDIAN memcpy((char*)&x + 1, src, 3); #elif __BYTE_ORDER == __BIG_ENDIAN memcpy(&x, src, 3); #endif x >>= 8; *dst = x * scaling; dst++; src += src_skip; } } void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { #ifdef __ARM_NEON__ unsigned long unrolled = nsamples / 4; nsamples = nsamples & 3; while (unrolled--) { float32x4_t samples = vld1q_f32(src); int16x4_t converted = float_16_neon(samples); converted = vreinterpret_s16_u8(vrev16_u8(vreinterpret_u8_s16(converted))); switch(dst_skip) { case 2: vst1_s16((int16_t*)dst, converted); break; default: vst1_lane_s16((int16_t*)(dst), converted, 0); vst1_lane_s16((int16_t*)(dst+dst_skip), converted, 1); vst1_lane_s16((int16_t*)(dst+2*dst_skip), converted, 2); vst1_lane_s16((int16_t*)(dst+3*dst_skip), converted, 3); break; } dst += 4*dst_skip; src+= 4; } #endif int16_t tmp; while (nsamples--) { // float_16 (*src, tmp); if (*src <= NORMALIZED_FLOAT_MIN) { tmp = SAMPLE_16BIT_MIN; } else if (*src >= NORMALIZED_FLOAT_MAX) { tmp = SAMPLE_16BIT_MAX; } else { tmp = (int16_t) f_round (*src * SAMPLE_16BIT_SCALING); } #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(tmp>>8); dst[1]=(char)(tmp); #elif __BYTE_ORDER == __BIG_ENDIAN dst[0]=(char)(tmp); dst[1]=(char)(tmp>>8); #endif dst += dst_skip; src++; } } void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { #ifdef __ARM_NEON__ unsigned long unrolled = nsamples / 4; nsamples = nsamples & 3; while (unrolled--) { float32x4_t samples = vld1q_f32(src); int16x4_t converted = float_16_neon(samples); switch(dst_skip) { case 2: vst1_s16((int16_t*)dst, converted); break; default: vst1_lane_s16((int16_t*)(dst), converted, 0); vst1_lane_s16((int16_t*)(dst+dst_skip), converted, 1); vst1_lane_s16((int16_t*)(dst+2*dst_skip), converted, 2); vst1_lane_s16((int16_t*)(dst+3*dst_skip), converted, 3); break; } dst += 4*dst_skip; src+= 4; } #endif while (nsamples--) { float_16 (*src, *((int16_t*) dst)); dst += dst_skip; src++; } } void sample_move_dither_rect_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { jack_default_audio_sample_t val; int16_t tmp; while (nsamples--) { val = (*src * SAMPLE_16BIT_SCALING) + fast_rand() / (float) UINT_MAX - 0.5f; float_16_scaled (val, tmp); #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(tmp>>8); dst[1]=(char)(tmp); #elif __BYTE_ORDER == __BIG_ENDIAN dst[0]=(char)(tmp); dst[1]=(char)(tmp>>8); #endif dst += dst_skip; src++; } } void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { jack_default_audio_sample_t val; while (nsamples--) { val = (*src * SAMPLE_16BIT_SCALING) + fast_rand() / (float)UINT_MAX - 0.5f; float_16_scaled (val, *((int16_t*) dst)); dst += dst_skip; src++; } } void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { jack_default_audio_sample_t val; int16_t tmp; while (nsamples--) { val = (*src * SAMPLE_16BIT_SCALING) + ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f; float_16_scaled (val, tmp); #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(tmp>>8); dst[1]=(char)(tmp); #elif __BYTE_ORDER == __BIG_ENDIAN dst[0]=(char)(tmp); dst[1]=(char)(tmp>>8); #endif dst += dst_skip; src++; } } void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { jack_default_audio_sample_t val; while (nsamples--) { val = (*src * SAMPLE_16BIT_SCALING) + ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f; float_16_scaled (val, *((int16_t*) dst)); dst += dst_skip; src++; } } void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { jack_default_audio_sample_t x; jack_default_audio_sample_t xe; /* the innput sample - filtered error */ jack_default_audio_sample_t xp; /* x' */ float r; float rm1 = state->rm1; unsigned int idx = state->idx; int16_t tmp; while (nsamples--) { x = *src * SAMPLE_16BIT_SCALING; r = ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f; /* Filter the error with Lipshitz's minimally audible FIR: [2.033 -2.165 1.959 -1.590 0.6149] */ xe = x - state->e[idx] * 2.033f + state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f - state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f + state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f - state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f; xp = xe + r - rm1; rm1 = r; float_16_scaled (xp, tmp); /* Intrinsic z^-1 delay */ idx = (idx + 1) & DITHER_BUF_MASK; state->e[idx] = xp - xe; #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(tmp>>8); dst[1]=(char)(tmp); #elif __BYTE_ORDER == __BIG_ENDIAN dst[0]=(char)(tmp); dst[1]=(char)(tmp>>8); #endif dst += dst_skip; src++; } state->rm1 = rm1; state->idx = idx; } void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { jack_default_audio_sample_t x; jack_default_audio_sample_t xe; /* the innput sample - filtered error */ jack_default_audio_sample_t xp; /* x' */ float r; float rm1 = state->rm1; unsigned int idx = state->idx; while (nsamples--) { x = *src * SAMPLE_16BIT_SCALING; r = ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f; /* Filter the error with Lipshitz's minimally audible FIR: [2.033 -2.165 1.959 -1.590 0.6149] */ xe = x - state->e[idx] * 2.033f + state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f - state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f + state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f - state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f; xp = xe + r - rm1; rm1 = r; float_16_scaled (xp, *((int16_t*) dst)); /* Intrinsic z^-1 delay */ idx = (idx + 1) & DITHER_BUF_MASK; state->e[idx] = *((int16_t*) dst) - xe; dst += dst_skip; src++; } state->rm1 = rm1; state->idx = idx; } void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { short z; const jack_default_audio_sample_t scaling = 1.0/SAMPLE_16BIT_SCALING; #ifdef __ARM_NEON__ const float32x4_t vscaling = vdupq_n_f32(scaling); unsigned long unrolled = nsamples / 4; while (unrolled--) { int16x4_t source16x4; switch(src_skip) { case 2: source16x4 = vld1_s16((int16_t*)src); break; case 4: source16x4 = vld2_s16((int16_t*)src).val[0]; break; default: source16x4 = vld1_lane_s16((int16_t*)src, source16x4, 0); source16x4 = vld1_lane_s16((int16_t*)(src+src_skip), source16x4, 1); source16x4 = vld1_lane_s16((int16_t*)(src+2*src_skip), source16x4, 2); source16x4 = vld1_lane_s16((int16_t*)(src+3*src_skip), source16x4, 3); break; } source16x4 = vreinterpret_s16_u8(vrev16_u8(vreinterpret_u8_s16(source16x4))); int32x4_t source32x4 = vmovl_s16(source16x4); src += 4 * src_skip; float32x4_t converted = vcvtq_f32_s32(source32x4); float32x4_t scaled = vmulq_f32(converted, vscaling); vst1q_f32(dst, scaled); dst += 4; } nsamples = nsamples & 3; #endif /* ALERT: signed sign-extension portability !!! */ while (nsamples--) { #if __BYTE_ORDER == __LITTLE_ENDIAN z = (unsigned char)(src[0]); z <<= 8; z |= (unsigned char)(src[1]); #elif __BYTE_ORDER == __BIG_ENDIAN z = (unsigned char)(src[1]); z <<= 8; z |= (unsigned char)(src[0]); #endif *dst = z * scaling; dst++; src += src_skip; } } void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { /* ALERT: signed sign-extension portability !!! */ const jack_default_audio_sample_t scaling = 1.0/SAMPLE_16BIT_SCALING; #ifdef __ARM_NEON__ const float32x4_t vscaling = vdupq_n_f32(scaling); unsigned long unrolled = nsamples / 4; while (unrolled--) { int16x4_t source16x4; switch(src_skip) { case 2: source16x4 = vld1_s16((int16_t*)src); break; case 4: source16x4 = vld2_s16((int16_t*)src).val[0]; break; default: source16x4 = vld1_lane_s16((int16_t*)src, source16x4, 0); source16x4 = vld1_lane_s16((int16_t*)(src+src_skip), source16x4, 1); source16x4 = vld1_lane_s16((int16_t*)(src+2*src_skip), source16x4, 2); source16x4 = vld1_lane_s16((int16_t*)(src+3*src_skip), source16x4, 3); break; } int32x4_t source32x4 = vmovl_s16(source16x4); src += 4 * src_skip; float32x4_t converted = vcvtq_f32_s32(source32x4); float32x4_t scaled = vmulq_f32(converted, vscaling); vst1q_f32(dst, scaled); dst += 4; } nsamples = nsamples & 3; #endif while (nsamples--) { *dst = (*((short *) src)) * scaling; dst++; src += src_skip; } } void memset_interleave (char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes) { switch (unit_bytes) { case 1: while (bytes--) { *dst = val; dst += skip_bytes; } break; case 2: while (bytes) { *((short *) dst) = (short) val; dst += skip_bytes; bytes -= 2; } break; case 4: while (bytes) { *((int *) dst) = (int) val; dst += skip_bytes; bytes -= 4; } break; default: while (bytes) { memset(dst, val, unit_bytes); dst += skip_bytes; bytes -= unit_bytes; } break; } } /* COPY FUNCTIONS: used to move data from an input channel to an output channel. Note that we assume that the skip distance is the same for both channels. This is completely fine unless the input and output were on different audio interfaces that were interleaved differently. We don't try to handle that. */ void memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar) { memcpy (dst, src, src_bytes); } void memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes) { while (src_bytes) { *((short *) dst) = *((short *) src); dst += dst_skip_bytes; src += src_skip_bytes; src_bytes -= 2; } } void memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes) { while (src_bytes) { memcpy(dst, src, 3); dst += dst_skip_bytes; src += src_skip_bytes; src_bytes -= 3; } } void memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes) { while (src_bytes) { *((int *) dst) = *((int *) src); dst += dst_skip_bytes; src += src_skip_bytes; src_bytes -= 4; } } 1.9.12~dfsg/common/JackNetOneDriver.cpp0000644000000000000000000012557113214314510016504 0ustar rootroot/* Copyright (C) 2008-2011 Torben Horn This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef WIN32 #include #endif #include "JackNetOneDriver.h" #include "JackEngineControl.h" #include "JackLockedEngine.h" #include "JackGraphManager.h" #include "JackWaitThreadedDriver.h" #include "JackTools.h" #include "driver_interface.h" #include "netjack.h" #include "netjack_packet.h" #if HAVE_SAMPLERATE #include #endif #if HAVE_CELT #include #endif #if HAVE_OPUS #include #include #endif #define MIN(x,y) ((x)<(y) ? (x) : (y)) using namespace std; namespace Jack { JackNetOneDriver::JackNetOneDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, int sample_rate, int period_size, int resample_factor, const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val) : JackWaiterDriver(name, alias, engine, table) { jack_log("JackNetOneDriver::JackNetOneDriver port %d", port); #ifdef WIN32 WSADATA wsa; WSAStartup(MAKEWORD(2, 0), &wsa); #endif netjack_init(& (this->netj), NULL, // client name, capture_ports, playback_ports, midi_input_ports, midi_output_ports, sample_rate, period_size, port, transport_sync, resample_factor, 0, bitdepth, use_autoconfig, latency, redundancy, dont_htonl_floats, always_deadline, jitter_val); } JackNetOneDriver::~JackNetOneDriver() { // No destructor yet. } //open, close, attach and detach------------------------------------------------------ int JackNetOneDriver::Close() { // Generic audio driver close int res = JackWaiterDriver::Close(); FreePorts(); netjack_release(&netj); return res; } int JackNetOneDriver::Attach() { return 0; } int JackNetOneDriver::Detach() { return 0; } int JackNetOneDriver::AllocPorts() { jack_port_id_t port_index; char buf[64]; unsigned int chn; //if (netj.handle_transport_sync) // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); for (chn = 0; chn < netj.capture_channels_audio; chn++) { snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } //port = fGraphManager->GetPort(port_index); netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index); if (netj.bitdepth == CELT_MODE) { #if HAVE_CELT #if HAVE_CELT_API_0_11 celt_int32 lookahead; CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create_custom(celt_mode, 1, NULL)); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 celt_int32 lookahead; CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create(celt_mode, 1, NULL)); #else celt_int32_t lookahead; CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL); netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create(celt_mode)); #endif celt_mode_info(celt_mode, CELT_GET_LOOKAHEAD, &lookahead); netj.codec_latency = 2 * lookahead; #endif } else if (netj.bitdepth == OPUS_MODE) { #if HAVE_OPUS OpusCustomMode *opus_mode = opus_custom_mode_create(netj.sample_rate, netj.period_size, NULL); // XXX free me in the end OpusCustomDecoder *decoder = opus_custom_decoder_create( opus_mode, 1, NULL ); netj.capture_srcs = jack_slist_append(netj.capture_srcs, decoder); #endif } else { #if HAVE_SAMPLERATE netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); #endif } } for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } //port = fGraphManager->GetPort(port_index); netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index); } for (chn = 0; chn < netj.playback_channels_audio; chn++) { snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } //port = fGraphManager->GetPort(port_index); netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index); if (netj.bitdepth == CELT_MODE) { #if HAVE_CELT #if HAVE_CELT_API_0_11 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create_custom(celt_mode, 1, NULL)); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode, 1, NULL)); #else CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL); netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode)); #endif #endif } else if (netj.bitdepth == OPUS_MODE) { #if HAVE_OPUS const int kbps = netj.resample_factor; jack_error("NEW ONE OPUS ENCODER 128 <> %d!!", kbps); int err; OpusCustomMode *opus_mode = opus_custom_mode_create( netj.sample_rate, netj.period_size, &err ); // XXX free me in the end if (err != OPUS_OK) { jack_error("opus mode failed"); } OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err ); if (err != OPUS_OK) { jack_error("opus mode failed"); } opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10)); opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY)); netj.playback_srcs = jack_slist_append(netj.playback_srcs, oe); #endif } else { #if HAVE_SAMPLERATE netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); #endif } } for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", buf); return -1; } //port = fGraphManager->GetPort(port_index); netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index); } return 0; } //init and restart-------------------------------------------------------------------- bool JackNetOneDriver::Initialize() { jack_log("JackNetOneDriver::Init"); FreePorts(); netjack_release(&netj); //display some additional infos jack_info("NetOne driver started"); if (netjack_startup(&netj)) { return false; } //register jack ports if (AllocPorts() != 0) { jack_error("Can't allocate ports."); return false; } //monitor //driver parametering JackTimedDriver::SetBufferSize(netj.period_size); JackTimedDriver::SetSampleRate(netj.sample_rate); JackDriver::NotifyBufferSize(netj.period_size); JackDriver::NotifySampleRate(netj.sample_rate); //transport engine parametering fEngineControl->fTransport.SetNetworkSync(true); return true; } //jack ports and buffers-------------------------------------------------------------- //driver processes-------------------------------------------------------------------- int JackNetOneDriver::Read() { int delay; delay = netjack_wait(&netj); if (delay) { NotifyXRun(fBeginDateUst, (float) delay); jack_error("netxruns... duration: %dms", delay / 1000); } if ((netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2) JackTools::ThrowJackNetException(); //netjack_read(&netj, netj.period_size); JackDriver::CycleTakeBeginTime(); jack_position_t local_trans_pos; jack_transport_state_t local_trans_state; unsigned int *packet_buf, *packet_bufX; if (! netj.packet_data_valid) { jack_log("data not valid"); render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats); return 0; } packet_buf = netj.rx_buf; jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); netj.reply_port = pkthdr->reply_port; netj.latency = pkthdr->latency; // Special handling for latency=0 if (netj.latency == 0) netj.resync_threshold = 0; else netj.resync_threshold = MIN(15, pkthdr->latency - 1); // check whether, we should handle the transport sync stuff, or leave trnasports untouched. if (netj.handle_transport_sync) { #if 1 unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); // read local transport info.... //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); local_trans_state = fEngineControl->fTransport.Query(&local_trans_pos); // Now check if we have to start or stop local transport to sync to remote... switch (pkthdr->transport_state) { case JackTransportStarting: // the master transport is starting... so we set our reply to the sync_callback; if (local_trans_state == JackTransportStopped) { fEngineControl->fTransport.SetCommand(TransportCommandStart); //jack_transport_start(netj.client); //last_transport_state = JackTransportStopped; netj.sync_state = 0; jack_info("locally stopped... starting..."); } if (local_trans_pos.frame != compensated_tranport_pos) { jack_position_t new_pos = local_trans_pos; new_pos.frame = compensated_tranport_pos + 2 * netj.period_size; new_pos.valid = (jack_position_bits_t) 0; fEngineControl->fTransport.RequestNewPos(&new_pos); //jack_transport_locate(netj.client, compensated_tranport_pos); //last_transport_state = JackTransportRolling; netj.sync_state = 0; jack_info("starting locate to %d", compensated_tranport_pos); } break; case JackTransportStopped: netj.sync_state = 1; if (local_trans_pos.frame != (pkthdr->transport_frame)) { jack_position_t new_pos = local_trans_pos; new_pos.frame = pkthdr->transport_frame; new_pos.valid = (jack_position_bits_t)0; fEngineControl->fTransport.RequestNewPos(&new_pos); //jack_transport_locate(netj.client, (pkthdr->transport_frame)); jack_info("transport is stopped locate to %d", pkthdr->transport_frame); } if (local_trans_state != JackTransportStopped) //jack_transport_stop(netj.client); fEngineControl->fTransport.SetCommand(TransportCommandStop); break; case JackTransportRolling: netj.sync_state = 1; // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); // } if (local_trans_state != JackTransportRolling) fEngineControl->fTransport.SetState(JackTransportRolling); break; case JackTransportLooping: break; } #endif } render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats); packet_cache_release_packet(netj.packcache, netj.expected_framecnt); return 0; } int JackNetOneDriver::Write() { int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0); uint32_t *packet_buf, *packet_bufX; int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); jacknet_packet_header *pkthdr; packet_buf = (uint32_t *) alloca(packet_size); pkthdr = (jacknet_packet_header *)packet_buf; if (netj.running_free) { return 0; } // offset packet_bufX by the packetheader. packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); pkthdr->sync_state = syncstate;; pkthdr->latency = netj.time_to_deadline; //printf("time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness); pkthdr->framecnt = netj.expected_framecnt; render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats); packet_header_hton(pkthdr); if (netj.srcaddress_valid) { unsigned int r; static const int flag = 0; if (netj.reply_port) netj.syncsource_address.sin_port = htons(netj.reply_port); for (r = 0; r < netj.redundancy; r++) netjack_sendto(netj.sockfd, (char *)packet_buf, packet_size, flag, (struct sockaddr*) & (netj.syncsource_address), sizeof(struct sockaddr_in), netj.mtu); } return 0; } void JackNetOneDriver::FreePorts () { JSList *node = netj.capture_ports; while (node != NULL) { JSList *this_node = node; jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; node = jack_slist_remove_link(node, this_node); jack_slist_free_1(this_node); fEngine->PortUnRegister(fClientControl.fRefNum, port_index); } netj.capture_ports = NULL; node = netj.playback_ports; while (node != NULL) { JSList *this_node = node; jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; node = jack_slist_remove_link(node, this_node); jack_slist_free_1(this_node); fEngine->PortUnRegister(fClientControl.fRefNum, port_index); } netj.playback_ports = NULL; if (netj.bitdepth == CELT_MODE) { #if HAVE_CELT node = netj.playback_srcs; while (node != NULL) { JSList *this_node = node; CELTEncoder *enc = (CELTEncoder *) node->data; node = jack_slist_remove_link(node, this_node); jack_slist_free_1(this_node); celt_encoder_destroy(enc); } netj.playback_srcs = NULL; node = netj.capture_srcs; while (node != NULL) { JSList *this_node = node; CELTDecoder *dec = (CELTDecoder *) node->data; node = jack_slist_remove_link(node, this_node); jack_slist_free_1(this_node); celt_decoder_destroy(dec); } netj.capture_srcs = NULL; #endif } else if (netj.bitdepth == OPUS_MODE) { #if HAVE_OPUS node = netj.playback_srcs; while (node != NULL) { JSList *this_node = node; OpusCustomEncoder *enc = (OpusCustomEncoder *) node->data; node = jack_slist_remove_link(node, this_node); jack_slist_free_1(this_node); opus_custom_encoder_destroy(enc); } netj.playback_srcs = NULL; node = netj.capture_srcs; while (node != NULL) { JSList *this_node = node; OpusCustomDecoder *dec = (OpusCustomDecoder *) node->data; node = jack_slist_remove_link(node, this_node); jack_slist_free_1(this_node); opus_custom_decoder_destroy(dec); } netj.capture_srcs = NULL; #endif } else { #if HAVE_SAMPLERATE node = netj.playback_srcs; while (node != NULL) { JSList *this_node = node; SRC_STATE *state = (SRC_STATE *) node->data; node = jack_slist_remove_link(node, this_node); jack_slist_free_1(this_node); src_delete(state); } netj.playback_srcs = NULL; node = netj.capture_srcs; while (node != NULL) { JSList *this_node = node; SRC_STATE *state = (SRC_STATE *) node->data; node = jack_slist_remove_link(node, this_node); jack_slist_free_1(this_node); src_delete(state); } netj.capture_srcs = NULL; #endif } } //Render functions-------------------------------------------------------------------- // render functions for float void JackNetOneDriver::render_payload_to_jack_ports_float(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) { uint32_t chn = 0; JSList *node = capture_ports; #if HAVE_SAMPLERATE JSList *src_node = capture_srcs; #endif uint32_t *packet_bufX = (uint32_t *)packet_payload; if (!packet_payload) return; while (node != NULL) { unsigned int i; int_float_t val; #if HAVE_SAMPLERATE SRC_DATA src; #endif jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); const char *porttype = port->GetType(); if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { #if HAVE_SAMPLERATE // audio port, resample if necessary if (net_period_down != nframes) { SRC_STATE *src_state = (SRC_STATE *)src_node->data; for (i = 0; i < net_period_down; i++) { packet_bufX[i] = ntohl (packet_bufX[i]); } src.data_in = (float *) packet_bufX; src.input_frames = net_period_down; src.data_out = buf; src.output_frames = nframes; src.src_ratio = (float) nframes / (float) net_period_down; src.end_of_input = 0; src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); src_node = jack_slist_next (src_node); } else #endif { if (dont_htonl_floats) { memcpy(buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t)); } else { for (i = 0; i < net_period_down; i++) { val.i = packet_bufX[i]; val.i = ntohl (val.i); buf[i] = val.f; } } } } else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down; uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); chn++; } } void JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) { uint32_t chn = 0; JSList *node = playback_ports; #if HAVE_SAMPLERATE JSList *src_node = playback_srcs; #endif uint32_t *packet_bufX = (uint32_t *) packet_payload; while (node != NULL) { #if HAVE_SAMPLERATE SRC_DATA src; #endif unsigned int i; int_float_t val; jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); const char *porttype = port->GetType(); if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { // audio port, resample if necessary #if HAVE_SAMPLERATE if (net_period_up != nframes) { SRC_STATE *src_state = (SRC_STATE *) src_node->data; src.data_in = buf; src.input_frames = nframes; src.data_out = (float *) packet_bufX; src.output_frames = net_period_up; src.src_ratio = (float) net_period_up / (float) nframes; src.end_of_input = 0; src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); for (i = 0; i < net_period_up; i++) { packet_bufX[i] = htonl (packet_bufX[i]); } src_node = jack_slist_next (src_node); } else #endif { if (dont_htonl_floats) { memcpy(packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t)); } else { for (i = 0; i < net_period_up; i++) { val.f = buf[i]; val.i = htonl (val.i); packet_bufX[i] = val.i; } } } } else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_up); node = jack_slist_next (node); chn++; } } #if HAVE_CELT // render functions for celt. void JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) { uint32_t chn = 0; JSList *node = capture_ports; JSList *src_node = capture_srcs; unsigned char *packet_bufX = (unsigned char *)packet_payload; while (node != NULL) { jack_port_id_t port_index = (jack_port_id_t) (intptr_t)node->data; JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); const char *portname = port->GetType(); if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { // audio port, decode celt data. CELTDecoder *decoder = (CELTDecoder *)src_node->data; #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 if (!packet_payload) celt_decode_float(decoder, NULL, net_period_down, buf, nframes); else celt_decode_float(decoder, packet_bufX, net_period_down, buf, nframes); #else if (!packet_payload) celt_decode_float(decoder, NULL, net_period_down, buf); else celt_decode_float(decoder, packet_bufX, net_period_down, buf); #endif src_node = jack_slist_next (src_node); } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; if (packet_payload) decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); chn++; } } void JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) { uint32_t chn = 0; JSList *node = playback_ports; JSList *src_node = playback_srcs; unsigned char *packet_bufX = (unsigned char *)packet_payload; while (node != NULL) { jack_port_id_t port_index = (jack_port_id_t) (intptr_t) node->data; JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); const char *portname = port->GetType(); if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { // audio port, encode celt data. int encoded_bytes; jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes); memcpy(floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t)); CELTEncoder *encoder = (CELTEncoder *)src_node->data; #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 encoded_bytes = celt_encode_float(encoder, floatbuf, nframes, packet_bufX, net_period_up); #else encoded_bytes = celt_encode_float(encoder, floatbuf, NULL, packet_bufX, net_period_up); #endif if (encoded_bytes != (int)net_period_up) jack_error("something in celt changed. netjack needs to be changed to handle this."); src_node = jack_slist_next(src_node); } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_up); node = jack_slist_next (node); chn++; } } #endif #if HAVE_OPUS #define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length) // render functions for Opus. void JackNetOneDriver::render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) { int chn = 0; JSList *node = capture_ports; JSList *src_node = capture_srcs; unsigned char *packet_bufX = (unsigned char *)packet_payload; while (node != NULL) { jack_port_id_t port_index = (jack_port_id_t) (intptr_t)node->data; JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); const char *portname = port->GetType(); if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { // audio port, decode opus data. OpusCustomDecoder *decoder = (OpusCustomDecoder*) src_node->data; if( !packet_payload ) memset(buf, 0, nframes * sizeof(float)); else { unsigned short len; memcpy(&len, packet_bufX, CDO); len = ntohs(len); opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes ); } src_node = jack_slist_next (src_node); } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; if( packet_payload ) decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); chn++; } } void JackNetOneDriver::render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) { int chn = 0; JSList *node = playback_ports; JSList *src_node = playback_srcs; unsigned char *packet_bufX = (unsigned char *)packet_payload; while (node != NULL) { jack_port_id_t port_index = (jack_port_id_t) (intptr_t) node->data; JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); const char *portname = port->GetType(); if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { // audio port, encode opus data. int encoded_bytes; jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes); memcpy(floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t)); OpusCustomEncoder *encoder = (OpusCustomEncoder*) src_node->data; encoded_bytes = opus_custom_encode_float( encoder, floatbuf, nframes, packet_bufX + CDO, net_period_up - CDO ); unsigned short len = htons(encoded_bytes); memcpy(packet_bufX, &len, CDO); src_node = jack_slist_next( src_node ); } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_up); node = jack_slist_next (node); chn++; } } #endif /* Wrapper functions with bitdepth argument... */ void JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) { #if HAVE_CELT if (bitdepth == CELT_MODE) render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); else #endif #if HAVE_OPUS if (bitdepth == OPUS_MODE) render_payload_to_jack_ports_opus (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); else #endif render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); } void JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) { #if HAVE_CELT if (bitdepth == CELT_MODE) render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); else #endif #if HAVE_OPUS if (bitdepth == OPUS_MODE) render_jack_ports_to_payload_opus (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); else #endif render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); } //driver loader----------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("netone", JackDriverMaster, "netjack one slave backend component", &filler); value.ui = 2U; jack_driver_descriptor_add_parameter(desc, &filler, "audio-ins", 'i', JackDriverParamUInt, &value, NULL, "Number of capture channels (defaults to 2)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "audio-outs", 'o', JackDriverParamUInt, &value, NULL, "Number of playback channels (defaults to 2)", NULL); value.ui = 1U; jack_driver_descriptor_add_parameter(desc, &filler, "midi-ins", 'I', JackDriverParamUInt, &value, NULL, "Number of midi capture channels (defaults to 1)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "midi-outs", 'O', JackDriverParamUInt, &value, NULL, "Number of midi playback channels (defaults to 1)", NULL); value.ui = 48000U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = 1024U; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.ui = 5U; jack_driver_descriptor_add_parameter(desc, &filler, "num-periods", 'n', JackDriverParamUInt, &value, NULL, "Network latency setting in no. of periods", NULL); value.ui = 3000U; jack_driver_descriptor_add_parameter(desc, &filler, "listen-port", 'l', JackDriverParamUInt, &value, NULL, "The socket port we are listening on for sync packets", NULL); value.ui = 1U; jack_driver_descriptor_add_parameter(desc, &filler, "factor", 'f', JackDriverParamUInt, &value, NULL, "Factor for sample rate reduction", NULL); value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "upstream-factor", 'u', JackDriverParamUInt, &value, NULL, "Factor for sample rate reduction on the upstream", NULL); #if HAVE_CELT value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamUInt, &value, NULL, "Set CELT encoding and number of kbits per channel", NULL); #endif #if HAVE_OPUS value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'P', JackDriverParamUInt, &value, NULL, "Set Opus encoding and number of kbits per channel", NULL); #endif value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "bit-depth", 'b', JackDriverParamUInt, &value, NULL, "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)", NULL); value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamBool, &value, NULL, "Whether to slave the transport to the master transport", NULL); value.ui = true; jack_driver_descriptor_add_parameter(desc, &filler, "autoconf", 'a', JackDriverParamBool, &value, NULL, "Whether to use Autoconfig, or just start", NULL); value.ui = 1U; jack_driver_descriptor_add_parameter(desc, &filler, "redundancy", 'R', JackDriverParamUInt, &value, NULL, "Send packets N times", NULL); value.ui = false; jack_driver_descriptor_add_parameter(desc, &filler, "native-endian", 'e', JackDriverParamBool, &value, NULL, "Dont convert samples to network byte order", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "jitterval", 'J', JackDriverParamInt, &value, NULL, "Attempted jitterbuffer microseconds on master", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "always-deadline", 'D', JackDriverParamBool, &value, NULL, "Always use deadline", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t sample_rate = 48000; jack_nframes_t resample_factor = 1; jack_nframes_t period_size = 1024; unsigned int capture_ports = 2; unsigned int playback_ports = 2; unsigned int capture_ports_midi = 1; unsigned int playback_ports_midi = 1; unsigned int listen_port = 3000; unsigned int bitdepth = 0; unsigned int handle_transport_sync = 1; unsigned int use_autoconfig = 1; unsigned int latency = 5; unsigned int redundancy = 1; unsigned int mtu = 1400; #if HAVE_SAMPLERATE unsigned int resample_factor_up = 1; #endif int dont_htonl_floats = 0; int always_deadline = 0; int jitter_val = 0; const JSList * node; const jack_driver_param_t * param; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'i': capture_ports = param->value.ui; break; case 'o': playback_ports = param->value.ui; break; case 'I': capture_ports_midi = param->value.ui; break; case 'O': playback_ports_midi = param->value.ui; break; case 'r': sample_rate = param->value.ui; break; case 'p': period_size = param->value.ui; break; case 'l': listen_port = param->value.ui; break; case 'f': #if HAVE_SAMPLERATE resample_factor = param->value.ui; #else jack_error("not built with libsamplerate support"); return NULL; #endif break; case 'u': #if HAVE_SAMPLERATE resample_factor_up = param->value.ui; #else jack_error("not built with libsamplerate support"); return NULL; #endif break; case 'b': bitdepth = param->value.ui; break; case 'c': #if HAVE_CELT bitdepth = CELT_MODE; resample_factor = param->value.ui; #else jack_error("not built with celt support"); return NULL; #endif break; case 'P': #if HAVE_OPUS bitdepth = OPUS_MODE; resample_factor = param->value.ui; jack_error("OPUS: %d\n", resample_factor); #else jack_error("not built with Opus support"); return NULL; #endif break; case 't': handle_transport_sync = param->value.ui; break; case 'a': use_autoconfig = param->value.ui; break; case 'n': latency = param->value.ui; break; case 'R': redundancy = param->value.ui; break; case 'H': dont_htonl_floats = param->value.ui; break; case 'J': jitter_val = param->value.i; break; case 'D': always_deadline = param->value.ui; break; } } try { Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver ( new Jack::JackNetOneDriver("system", "net_pcm", engine, table, listen_port, mtu, capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, sample_rate, period_size, resample_factor, "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, dont_htonl_floats, always_deadline, jitter_val)); if (driver->Open(period_size, sample_rate, 1, 1, capture_ports, playback_ports, 0, "from_master", "to_master", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } catch (...) { return NULL; } } #ifdef __cplusplus } #endif } 1.9.12~dfsg/common/JackMessageBuffer.h0000644000000000000000000000502613214314510016313 0ustar rootroot/* * messagebuffer.h -- realtime-safe message interface for jackd. * * This function is included in libjack so backend drivers can use * it, *not* for external client processes. The VERBOSE() and * MESSAGE() macros are realtime-safe. */ /* * Copyright (C) 2004 Rui Nuno Capela, Steve Harris * Copyright (C) 2008 Nedko Arnaudov * Copyright (C) 2008 Grame * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __JackMessageBuffer__ #define __JackMessageBuffer__ #include "JackPlatformPlug.h" #include "JackMutex.h" #include "JackAtomic.h" namespace Jack { /* MB_NEXT() relies on the fact that MB_BUFFERS is a power of two */ #define MB_BUFFERS 128 #define MB_NEXT(index) ((index+1) & (MB_BUFFERS-1)) #define MB_BUFFERSIZE 256 /* message length limit */ struct JackMessage { int level; char message[MB_BUFFERSIZE]; }; /*! \brief Message buffer to be used from RT threads. */ class JackMessageBuffer : public JackRunnableInterface { private: volatile JackThreadInitCallback fInit; void* fInitArg; JackMessage fBuffers[MB_BUFFERS]; JackThread fThread; JackProcessSync fGuard; volatile unsigned int fInBuffer; volatile unsigned int fOutBuffer; SInt32 fOverruns; bool fRunning; void Flush(); bool Start(); bool Stop(); public: JackMessageBuffer(); ~JackMessageBuffer(); // JackRunnableInterface interface bool Execute(); bool static Create(); bool static Destroy(); void AddMessage(int level, const char *message); int SetInitCallback(JackThreadInitCallback callback, void *arg); static JackMessageBuffer* fInstance; }; #ifdef __cplusplus extern "C" { #endif void JackMessageBufferAdd(int level, const char *message); #ifdef __cplusplus } #endif }; #endif 1.9.12~dfsg/common/JackAudioAdapter.h0000644000000000000000000000420613214314510016136 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackAudioAdapter__ #define __JackAudioAdapter__ #include "JackAudioAdapterInterface.h" #include "driver_interface.h" namespace Jack { /*! \brief Audio adapter : Jack client side. */ class JackAudioAdapter { private: static int Process(jack_nframes_t, void* arg); static int BufferSize(jack_nframes_t buffer_size, void* arg); static int SampleRate(jack_nframes_t sample_rate, void* arg); static void Latency(jack_latency_callback_mode_t mode, void* arg); jack_port_t** fCapturePortList; jack_port_t** fPlaybackPortList; jack_default_audio_sample_t** fInputBufferList; jack_default_audio_sample_t** fOutputBufferList; jack_client_t* fClient; JackAudioAdapterInterface* fAudioAdapter; bool fAutoConnect; void FreePorts(); void ConnectPorts(); void Reset(); int ProcessAux(jack_nframes_t frames); public: JackAudioAdapter(jack_client_t* client, JackAudioAdapterInterface* audio_io, const JSList* params = NULL); ~JackAudioAdapter(); int Open(); int Close(); }; } #define CaptureDriverFlags static_cast(JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal) #define PlaybackDriverFlags static_cast(JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal) #endif 1.9.12~dfsg/common/JackExternalClient.cpp0000644000000000000000000000526513214314510017056 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackExternalClient.h" #include "JackClientControl.h" #include "JackGlobals.h" #include "JackChannel.h" #include "JackError.h" namespace Jack { JackExternalClient::JackExternalClient(): fClientControl(NULL) {} JackExternalClient::~JackExternalClient() {} int JackExternalClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int result = -1; jack_log("JackExternalClient::ClientNotify ref = %ld client = %s name = %s notify = %ld", refnum, fClientControl->fName, name, notify); fChannel.ClientNotify(refnum, name, notify, sync, message, value1, value2, &result); return result; } int JackExternalClient::Open(const char* name, int pid, int refnum, int uuid, int* shared_client) { try { if (fChannel.Open(name) < 0) { jack_error("Cannot connect to client name = %s\n", name); return -1; } // Use "placement new" to allocate object in shared memory JackShmMemAble* shared_mem = static_cast(JackShmMem::operator new(sizeof(JackClientControl))); shared_mem->Init(); fClientControl = new(shared_mem) JackClientControl(name, pid, refnum, uuid); if (!fClientControl) { jack_error("Cannot allocate client shared memory segment"); return -1; } *shared_client = shared_mem->GetShmIndex(); jack_log("JackExternalClient::Open name = %s index = %ld base = %x", name, shared_mem->GetShmIndex(), shared_mem->GetShmAddress()); return 0; } catch (std::exception e) { return -1; } } int JackExternalClient::Close() { jack_log("JackExternalClient::Close"); fChannel.Close(); if (fClientControl) { fClientControl->~JackClientControl(); JackShmMem::operator delete(fClientControl); } return 0; } JackClientControl* JackExternalClient::GetClientControl() const { return fClientControl; } } // end of namespace 1.9.12~dfsg/common/JackAC3Encoder.cpp0000644000000000000000000002254513214314510016003 0ustar rootroot/* Copyright (C) 2006 Jesse Chappell (AC3Jack) Copyright (C) 2012 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAC3Encoder.h" #include "JackError.h" #include #include #include #define max(x,y) (((x)>(y)) ? (x) : (y)) #define min(x,y) (((x)<(y)) ? (x) : (y)) namespace Jack { #ifndef __ppc__ JackAC3Encoder::JackAC3Encoder(const JackAC3EncoderParams& params) { aften_set_defaults(&fAftenContext); fAftenContext.channels = params.channels; fAftenContext.samplerate = params.sample_rate; fAftenContext.params.bitrate = params.bitrate; int acmod = A52_ACMOD_MONO; int lfe = params.lfe; switch (params.channels) { case 1: acmod = A52_ACMOD_MONO; break; case 2: acmod = A52_ACMOD_STEREO; break; case 3: acmod = A52_ACMOD_3_0; break; case 4: acmod = A52_ACMOD_2_2; break; case 5: acmod = A52_ACMOD_3_2; break; break; default: break; } if (lfe) { fAftenContext.channels += 1; } fAftenContext.acmod = acmod; fAftenContext.lfe = lfe; fAftenContext.sample_format = A52_SAMPLE_FMT_FLT; fAftenContext.verbose = 1; fAftenContext.system.n_threads = 1; // create interleaved framebuffer for MAX_AC3_CHANNELS fSampleBuffer = new float[MAX_AC3_CHANNELS * A52_SAMPLES_PER_FRAME]; // create AC3 buffer fAC3Buffer = new unsigned char[A52_MAX_CODED_FRAME_SIZE]; memset(fAC3Buffer, 0, A52_MAX_CODED_FRAME_SIZE); fZeroBuffer = new unsigned char[SPDIF_FRAME_SIZE]; memset(fZeroBuffer, 0, SPDIF_FRAME_SIZE); fRingBuffer = jack_ringbuffer_create(32768); fOutSizeByte = 0; fFramePos = 0; fSampleRate = 0; fByteRate = 0; } bool JackAC3Encoder::Init(jack_nframes_t sample_rate) { fSampleRate = sample_rate; fByteRate = fSampleRate * sizeof(short) * 2; return (aften_encode_init(&fAftenContext) == 0); } JackAC3Encoder::~JackAC3Encoder() { aften_encode_close(&fAftenContext); delete [] fSampleBuffer; delete [] fAC3Buffer; delete [] fZeroBuffer; if (fRingBuffer) { jack_ringbuffer_free(fRingBuffer); } } void JackAC3Encoder::Process(float** inputs_buffer, float** outputs_buffer, int nframes) { // fill and process frame buffers as appropriate jack_nframes_t frames_left = A52_SAMPLES_PER_FRAME - fFramePos; jack_nframes_t offset = 0; while (offset < nframes) { if ((nframes - offset) >= frames_left) { // copy only frames_left more data jack_nframes_t pos = fFramePos * fAftenContext.channels; for (jack_nframes_t spos = offset; spos < offset + frames_left; ++spos) { for (size_t i = 0; i < fAftenContext.channels; ++i) { fSampleBuffer[pos + i] = inputs_buffer[i][spos]; } pos += fAftenContext.channels; } // use interleaved version int res = aften_encode_frame(&fAftenContext, fAC3Buffer + SPDIF_HEADER_SIZE, fSampleBuffer); if (res < 0) { jack_error("aften_encode_frame error !!"); return; } fOutSizeByte = res; FillSpdifHeader(fAC3Buffer, fOutSizeByte + SPDIF_HEADER_SIZE); // push AC3 output to SPDIF ring buffer float calc_ac3byterate = (fOutSizeByte * fSampleRate / (float) A52_SAMPLES_PER_FRAME); jack_nframes_t silencebytes = (jack_nframes_t) (fOutSizeByte * (fByteRate / calc_ac3byterate)) - fOutSizeByte - SPDIF_HEADER_SIZE; jack_ringbuffer_write(fRingBuffer, (const char *)fAC3Buffer, fOutSizeByte + SPDIF_HEADER_SIZE); // write the proper remainder of zero padding (inefficient, should be memsetting) jack_ringbuffer_write(fRingBuffer, (const char *)fZeroBuffer, silencebytes); offset += frames_left; frames_left = A52_SAMPLES_PER_FRAME; fFramePos = 0; } else { // copy incoming data into frame buffers without processing jack_nframes_t pos = fFramePos * fAftenContext.channels; for (jack_nframes_t spos = offset; spos < nframes; ++spos) { for (size_t i = 0; i < fAftenContext.channels; ++i) { fSampleBuffer[pos + i] = inputs_buffer[i][spos]; } pos += fAftenContext.channels; } fFramePos += (nframes - offset); offset += (nframes-offset); } } Output2Driver(outputs_buffer, nframes); } void JackAC3Encoder::FillSpdifHeader(unsigned char* buf, int outsize) { // todo, use outsize and not assume the fixed frame size? int ac3outsize = outsize - SPDIF_HEADER_SIZE; buf[0] = 0x72; buf[1] = 0xf8; /* spdif syncword */ buf[2] = 0x1f; buf[3] = 0x4e; /* .............. */ buf[4] = 0x01; /* AC3 data */ buf[5] = buf[13] & 7; /* bsmod, stream = 0 */ buf[6] = (ac3outsize << 3) & 0xff; buf[7] = (ac3outsize >> 5) & 0xff; #if !IS_BIGENDIAN swab(buf+SPDIF_HEADER_SIZE, buf + SPDIF_HEADER_SIZE, ac3outsize); #endif } int JackAC3Encoder::Output2Driver(float** outputs, jack_nframes_t nframes) { int wrotebytes = 0; jack_nframes_t nframes_left = nframes; if (jack_ringbuffer_read_space(fRingBuffer) == 0) { // just write silence memset(outputs[0], 0, nframes * sizeof(jack_default_audio_sample_t)); memset(outputs[1], 0, nframes * sizeof(jack_default_audio_sample_t)); } else { jack_ringbuffer_data_t rb_data[2]; jack_ringbuffer_get_read_vector(fRingBuffer, rb_data); while (nframes_left > 0 && rb_data[0].len > 4) { jack_nframes_t towrite_frames = (rb_data[0].len) / (sizeof(short) * 2); towrite_frames = min(towrite_frames, nframes_left); // write and deinterleave into the two channels #if 1 sample_move_dS_s16(outputs[0] + (nframes - nframes_left), (char *) rb_data[0].buf, towrite_frames, sizeof(short) * 2); sample_move_dS_s16(outputs[1] + (nframes - nframes_left), (char *) rb_data[0].buf + sizeof(short), towrite_frames, sizeof(short) * 2); #else sample_move_dS_s16_24ph(outputs[0] + (nframes - nframes_left), (char *) rb_data[0].buf, towrite_frames, sizeof(short) * 2); sample_move_dS_s16_24ph(outputs[1] + (nframes - nframes_left), (char *) rb_data[0].buf + sizeof(short), towrite_frames, sizeof(short) * 2); #endif wrotebytes = towrite_frames * sizeof(short) * 2; nframes_left -= towrite_frames; jack_ringbuffer_read_advance(fRingBuffer, wrotebytes); jack_ringbuffer_get_read_vector(fRingBuffer, rb_data); } if (nframes_left > 0) { // write silence memset(outputs[0] + (nframes - nframes_left), 0, (nframes_left) * sizeof(jack_default_audio_sample_t)); memset(outputs[1] + (nframes - nframes_left), 0, (nframes_left) * sizeof(jack_default_audio_sample_t)); } } return wrotebytes; } void JackAC3Encoder::sample_move_dS_s16(jack_default_audio_sample_t* dst, char *src, jack_nframes_t nsamples, unsigned long src_skip) { /* ALERT: signed sign-extension portability !!! */ while (nsamples--) { *dst = (*((short *) src)) / SAMPLE_MAX_16BIT; dst++; src += src_skip; } } void JackAC3Encoder::sample_move_dS_s16_24ph(jack_default_audio_sample_t* dst, char *src, jack_nframes_t nsamples, unsigned long src_skip) { /* ALERT: signed sign-extension portability !!! */ while (nsamples--) { *dst = (((int)(*((short *) src))) << 8) / SAMPLE_MAX_24BIT; dst++; src += src_skip; } } void JackAC3Encoder::GetChannelName(const char* name, const char* alias, char* portname, int channel) { /* * 2 channels = L, R * 3 channels = L, C, R * 4 channels = L, R, LS, RS * 5 ch = L, C, R, LS, RS * 6 ch = L, C, R, LS, RS, LFE */ const char* AC3_name = ""; switch (channel) { case 0: AC3_name = "AC3_1_Left"; break; case 1: if (fAftenContext.channels == 2 || fAftenContext.channels == 4) { AC3_name = "AC3_2_Right"; } else { AC3_name = "AC3_2_Center"; } break; case 2: if (fAftenContext.channels == 4) { AC3_name = "AC3_3_LeftSurround"; } else { AC3_name = "AC3_3_Right"; } break; case 3: if (fAftenContext.channels == 4) { AC3_name = "AC3_4_RightSurround"; } else { AC3_name = "AC3_4_LeftSurround"; } break; case 4: if (fAftenContext.channels > 4) { AC3_name = "AC3_5_RightSurround"; } break; default: break; } // Last channel if (fAftenContext.lfe && (channel == fAftenContext.channels - 1)) { sprintf(portname, "%s:%s:AC3_%d_LFE", name, alias, fAftenContext.channels); } else { sprintf(portname, "%s:%s:%s", name, alias, AC3_name); } } #endif } // end of namespace1.9.12~dfsg/common/JackControlAPI.h0000644000000000000000000001614013214314510015546 0ustar rootroot/* JACK control API Copyright (C) 2008 Nedko Arnaudov Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackControlAPI__ #define __JackControlAPI__ #include "jslist.h" #include "JackCompilerDeps.h" /** Parameter types, intentionally similar to jack_driver_param_type_t */ typedef enum { JackParamInt = 1, /**< @brief value type is a signed integer */ JackParamUInt, /**< @brief value type is an unsigned integer */ JackParamChar, /**< @brief value type is a char */ JackParamString, /**< @brief value type is a string with max size of ::JACK_PARAM_STRING_MAX+1 chars */ JackParamBool, /**< @brief value type is a boolean */ } jackctl_param_type_t; /** Driver types, intentionally similar to jack_driver_type_t */ typedef enum { JackMaster = 1, /**< @brief master driver */ JackSlave, /**< @brief slave driver */ } jackctl_driver_type_t; /** @brief Max value that jackctl_param_type_t type can have */ #define JACK_PARAM_MAX (JackParamBool + 1) /** @brief Max length of string parameter value, excluding terminating nul char */ #define JACK_PARAM_STRING_MAX 127 /** @brief Type for parameter value */ /* intentionally similar to jack_driver_param_value_t */ union jackctl_parameter_value { uint32_t ui; /**< @brief member used for ::JackParamUInt */ int32_t i; /**< @brief member used for ::JackParamInt */ char c; /**< @brief member used for ::JackParamChar */ char str[JACK_PARAM_STRING_MAX + 1]; /**< @brief member used for ::JackParamString */ bool b; /**< @brief member used for ::JackParamBool */ }; /** opaque type for server object */ typedef struct jackctl_server jackctl_server_t; /** opaque type for driver object */ typedef struct jackctl_driver jackctl_driver_t; /** opaque type for internal client object */ typedef struct jackctl_internal jackctl_internal_t; /** opaque type for parameter object */ typedef struct jackctl_parameter jackctl_parameter_t; /** opaque type for sigmask object */ typedef struct jackctl_sigmask jackctl_sigmask_t; #ifdef __cplusplus extern "C" { #endif #if 0 } /* Adjust editor indent */ #endif SERVER_EXPORT jackctl_sigmask_t * jackctl_setup_signals( unsigned int flags); SERVER_EXPORT void jackctl_wait_signals( jackctl_sigmask_t * signals); SERVER_EXPORT jackctl_server_t * jackctl_server_create( bool (* on_device_acquire)(const char * device_name), void (* on_device_release)(const char * device_name)); SERVER_EXPORT void jackctl_server_destroy( jackctl_server_t * server); SERVER_EXPORT const JSList * jackctl_server_get_drivers_list( jackctl_server_t * server); SERVER_EXPORT bool jackctl_server_open( jackctl_server_t * server, jackctl_driver_t * driver); SERVER_EXPORT bool jackctl_server_start( jackctl_server_t * server); SERVER_EXPORT bool jackctl_server_stop( jackctl_server_t * server); SERVER_EXPORT bool jackctl_server_close( jackctl_server_t * server); SERVER_EXPORT const JSList * jackctl_server_get_parameters( jackctl_server_t * server); SERVER_EXPORT const char * jackctl_driver_get_name( jackctl_driver_t * driver); SERVER_EXPORT jackctl_driver_type_t jackctl_driver_get_type( jackctl_driver_t * driver); SERVER_EXPORT const JSList * jackctl_driver_get_parameters( jackctl_driver_t * driver); SERVER_EXPORT const char * jackctl_parameter_get_name( jackctl_parameter_t * parameter); SERVER_EXPORT const char * jackctl_parameter_get_short_description( jackctl_parameter_t * parameter); SERVER_EXPORT const char * jackctl_parameter_get_long_description( jackctl_parameter_t * parameter); SERVER_EXPORT jackctl_param_type_t jackctl_parameter_get_type( jackctl_parameter_t * parameter); SERVER_EXPORT char jackctl_parameter_get_id( jackctl_parameter_t * parameter); SERVER_EXPORT bool jackctl_parameter_is_set( jackctl_parameter_t * parameter); SERVER_EXPORT bool jackctl_parameter_reset( jackctl_parameter_t * parameter); SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_value( jackctl_parameter_t * parameter); SERVER_EXPORT bool jackctl_parameter_set_value( jackctl_parameter_t * parameter, const union jackctl_parameter_value * value_ptr); SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value( jackctl_parameter_t * parameter); SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value( jackctl_parameter *parameter_ptr); SERVER_EXPORT bool jackctl_parameter_has_range_constraint( jackctl_parameter_t * parameter_ptr); SERVER_EXPORT bool jackctl_parameter_has_enum_constraint( jackctl_parameter_t * parameter_ptr); SERVER_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count( jackctl_parameter_t * parameter_ptr); SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value( jackctl_parameter_t * parameter_ptr, uint32_t index); SERVER_EXPORT const char * jackctl_parameter_get_enum_constraint_description( jackctl_parameter_t * parameter_ptr, uint32_t index); SERVER_EXPORT void jackctl_parameter_get_range_constraint( jackctl_parameter_t * parameter_ptr, union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr); SERVER_EXPORT bool jackctl_parameter_constraint_is_strict( jackctl_parameter_t * parameter_ptr); SERVER_EXPORT bool jackctl_parameter_constraint_is_fake_value( jackctl_parameter_t * parameter_ptr); SERVER_EXPORT const JSList * jackctl_server_get_internals_list( jackctl_server *server_ptr); SERVER_EXPORT const char * jackctl_internal_get_name( jackctl_internal *internal_ptr); SERVER_EXPORT const JSList * jackctl_internal_get_parameters( jackctl_internal *internal_ptr); SERVER_EXPORT bool jackctl_server_load_internal( jackctl_server * server, jackctl_internal * internal); SERVER_EXPORT bool jackctl_server_unload_internal( jackctl_server * server, jackctl_internal * internal); SERVER_EXPORT bool jackctl_server_load_session_file( jackctl_server * server_ptr, const char * file); SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server_t * server, jackctl_driver_t * driver); SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server_t * server, jackctl_driver_t * driver); SERVER_EXPORT bool jackctl_server_switch_master(jackctl_server_t * server, jackctl_driver_t * driver); SERVER_EXPORT int jackctl_parse_driver_params(jackctl_driver * driver_ptr, int argc, char* argv[]); #if 0 { /* Adjust editor indent */ #endif #ifdef __cplusplus } /* extern "C" */ #endif #endif 1.9.12~dfsg/common/JackPort.cpp0000644000000000000000000001605113214314510015054 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackPort.h" #include "JackError.h" #include "JackPortType.h" #include #include namespace Jack { JackPort::JackPort() { Release(); } bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) { jack_port_type_id_t id = GetPortTypeId(port_type); assert(id >= 0 && id <= PORT_TYPES_MAX); if (id == PORT_TYPES_MAX) { return false; } fTypeId = id; fFlags = flags; fRefNum = refnum; strcpy(fName, port_name); fInUse = true; fLatency = 0; fTotalLatency = 0; fMonitorRequests = 0; fPlaybackLatency.min = fPlaybackLatency.max = 0; fCaptureLatency.min = fCaptureLatency.max = 0; fTied = NO_PORT; fAlias1[0] = '\0'; fAlias2[0] = '\0'; // DB: At this point we do not know current buffer size in frames, // but every time buffer will be returned to any user, // it will be called with either ClearBuffer or MixBuffers // with correct current buffer size. // So it is safe to init with 0 here. ClearBuffer(0); return true; } void JackPort::Release() { fTypeId = 0; fFlags = JackPortIsInput; fRefNum = -1; fInUse = false; fLatency = 0; fTotalLatency = 0; fMonitorRequests = 0; fPlaybackLatency.min = fPlaybackLatency.max = 0; fCaptureLatency.min = fCaptureLatency.max = 0; fTied = NO_PORT; fAlias1[0] = '\0'; fAlias2[0] = '\0'; } int JackPort::GetRefNum() const { return fRefNum; } jack_nframes_t JackPort::GetLatency() const { return fLatency; } jack_nframes_t JackPort::GetTotalLatency() const { return fTotalLatency; } void JackPort::SetLatency(jack_nframes_t nframes) { fLatency = nframes; /* setup the new latency values here, * so we dont need to change the backend codes. */ if (fFlags & JackPortIsOutput) { fCaptureLatency.min = nframes; fCaptureLatency.max = nframes; } if (fFlags & JackPortIsInput) { fPlaybackLatency.min = nframes; fPlaybackLatency.max = nframes; } } void JackPort::SetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) { if (mode == JackCaptureLatency) { fCaptureLatency = *range; /* hack to set latency up for * backend ports */ if ((fFlags & JackPortIsOutput) && (fFlags & JackPortIsPhysical)) { fLatency = (range->min + range->max) / 2; } } else { fPlaybackLatency = *range; /* hack to set latency up for * backend ports */ if ((fFlags & JackPortIsInput) && (fFlags & JackPortIsPhysical)) { fLatency = (range->min + range->max) / 2; } } } void JackPort::GetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) const { if (mode == JackCaptureLatency) { *range = fCaptureLatency; } else { *range = fPlaybackLatency; } } int JackPort::Tie(jack_port_id_t port_index) { fTied = port_index; return 0; } int JackPort::UnTie() { fTied = NO_PORT; return 0; } int JackPort::RequestMonitor(bool onoff) { /** jackd.h * If @ref JackPortCanMonitor is set for this @a port, turn input * monitoring on or off. Otherwise, do nothing. if (!(fFlags & JackPortCanMonitor)) return -1; */ if (onoff) { fMonitorRequests++; } else if (fMonitorRequests) { fMonitorRequests--; } return 0; } int JackPort::EnsureMonitor(bool onoff) { /** jackd.h * If @ref JackPortCanMonitor is set for this @a port, turn input * monitoring on or off. Otherwise, do nothing. if (!(fFlags & JackPortCanMonitor)) return -1; */ if (onoff) { if (fMonitorRequests == 0) { fMonitorRequests++; } } else { if (fMonitorRequests > 0) { fMonitorRequests = 0; } } return 0; } const char* JackPort::GetName() const { return fName; } const char* JackPort::GetShortName() const { /* we know there is always a colon, because we put it there ... */ return strchr(fName, ':') + 1; } int JackPort::GetFlags() const { return fFlags; } const char* JackPort::GetType() const { const JackPortType* type = GetPortType(fTypeId); return type->fName; } void JackPort::SetName(const char* new_name) { char* colon = strchr(fName, ':'); int len = sizeof(fName) - ((int) (colon - fName)) - 2; snprintf(colon + 1, len, "%s", new_name); } bool JackPort::NameEquals(const char* target) { char buf[REAL_JACK_PORT_NAME_SIZE+1]; /* this nasty, nasty kludge is here because between 0.109.0 and 0.109.1, the ALSA audio backend had the name "ALSA", whereas as before and after it, it was called "alsa_pcm". this stops breakage for any setups that have saved "alsa_pcm" or "ALSA" in their connection state. */ if (strncmp(target, "ALSA:capture", 12) == 0 || strncmp(target, "ALSA:playback", 13) == 0) { snprintf(buf, sizeof(buf), "alsa_pcm%s", target + 4); target = buf; } return (strcmp(fName, target) == 0 || strcmp(fAlias1, target) == 0 || strcmp(fAlias2, target) == 0); } int JackPort::GetAliases(char* const aliases[2]) { int cnt = 0; if (fAlias1[0] != '\0') { snprintf(aliases[0], REAL_JACK_PORT_NAME_SIZE, "%s", fAlias1); cnt++; } if (fAlias2[0] != '\0') { snprintf(aliases[1], REAL_JACK_PORT_NAME_SIZE, "%s", fAlias2); cnt++; } return cnt; } int JackPort::SetAlias(const char* alias) { if (fAlias1[0] == '\0') { snprintf(fAlias1, sizeof(fAlias1), "%s", alias); } else if (fAlias2[0] == '\0') { snprintf(fAlias2, sizeof(fAlias2), "%s", alias); } else { return -1; } return 0; } int JackPort::UnsetAlias(const char* alias) { if (strcmp(fAlias1, alias) == 0) { fAlias1[0] = '\0'; } else if (strcmp(fAlias2, alias) == 0) { fAlias2[0] = '\0'; } else { return -1; } return 0; } void JackPort::ClearBuffer(jack_nframes_t frames) { const JackPortType* type = GetPortType(fTypeId); (type->init)(GetBuffer(), frames * sizeof(jack_default_audio_sample_t), frames); } void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size) { const JackPortType* type = GetPortType(fTypeId); (type->mixdown)(GetBuffer(), src_buffers, src_count, buffer_size); } } // end of namespace 1.9.12~dfsg/common/JackPlatformPlug.h0000644000000000000000000000151013214314510016203 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPlatformPlug__ #define __JackPlatformPlug__ #include "JackPlatformPlug_os.h" #endif 1.9.12~dfsg/common/JackDriverInfo.h0000644000000000000000000000301613214314510015641 0ustar rootroot/* Copyright (C) 2001-2005 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackDriverInfo__ #define __JackDriverInfo__ #include "driver_interface.h" #include "JackDriver.h" #include "JackSystemDeps.h" typedef Jack::JackDriverClientInterface* (*driverInitialize) (Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); class SERVER_EXPORT JackDriverInfo { private: driverInitialize fInitialize; DRIVER_HANDLE fHandle; Jack::JackDriverClientInterface* fBackend; public: JackDriverInfo():fInitialize(NULL),fHandle(NULL),fBackend(NULL) {} ~JackDriverInfo(); Jack::JackDriverClientInterface* Open(jack_driver_desc_t* driver_desc, Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); Jack::JackDriverClientInterface* GetBackend() { return fBackend; } }; #endif 1.9.12~dfsg/common/JackTransportEngine.cpp0000644000000000000000000002535613214314510017262 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackTransportEngine.h" #include "JackClientInterface.h" #include "JackClientControl.h" #include "JackEngineControl.h" #include "JackGlobals.h" #include "JackError.h" #include "JackTime.h" #include #include #include using namespace std; namespace Jack { JackTransportEngine::JackTransportEngine(): JackAtomicArrayState() { fTransportState = JackTransportStopped; fTransportCmd = fPreviousCmd = TransportCommandStop; fSyncTimeout = 10000000; /* 10 seconds default... in case of big netjack1 roundtrip */ fSyncTimeLeft = 0; fTimeBaseMaster = -1; fWriteCounter = 0; fConditionnal = false; fPendingPos = false; fNetworkSync = false; } // compute the number of cycle for timeout void JackTransportEngine::SyncTimeout(jack_nframes_t frame_rate, jack_nframes_t buffer_size) { long buf_usecs = (long)((buffer_size * (jack_time_t)1000000) / frame_rate); fSyncTimeLeft = fSyncTimeout / buf_usecs; jack_log("SyncTimeout fSyncTimeout = %ld fSyncTimeLeft = %ld", (long)fSyncTimeout, (long)fSyncTimeLeft); } // Server int JackTransportEngine::ResetTimebase(int refnum) { if (fTimeBaseMaster == refnum) { jack_position_t* request = WriteNextStateStart(2); // To check request->valid = (jack_position_bits_t)0; WriteNextStateStop(2); fTimeBaseMaster = -1; return 0; } else { return EINVAL; } } // Server int JackTransportEngine::SetTimebaseMaster(int refnum, bool conditionnal) { if (conditionnal && fTimeBaseMaster > 0) { if (refnum != fTimeBaseMaster) { jack_log("conditional timebase for ref = %ld failed: %ld is already the master", refnum, fTimeBaseMaster); return EBUSY; } else { jack_log("ref = %ld was already timebase master", refnum); return 0; } } else { fTimeBaseMaster = refnum; fConditionnal = conditionnal; jack_log("new timebase master: ref = %ld", refnum); return 0; } } // RT bool JackTransportEngine::CheckAllRolling(JackClientInterface** table) { for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client && client->GetClientControl()->fTransportState != JackTransportRolling) { jack_log("CheckAllRolling ref = %ld is not rolling", i); return false; } } jack_log("CheckAllRolling"); return true; } // RT void JackTransportEngine::MakeAllStartingLocating(JackClientInterface** table) { for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); // Inactive clients don't have their process function called at all, so they must appear as already "rolling" for the transport.... control->fTransportState = (control->fActive && control->fCallback[kRealTimeCallback]) ? JackTransportStarting : JackTransportRolling; control->fTransportSync = true; control->fTransportTimebase = true; jack_log("MakeAllStartingLocating ref = %ld", i); } } } // RT void JackTransportEngine::MakeAllStopping(JackClientInterface** table) { for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); control->fTransportState = JackTransportStopped; control->fTransportSync = false; control->fTransportTimebase = false; jack_log("MakeAllStopping ref = %ld", i); } } } // RT void JackTransportEngine::MakeAllLocating(JackClientInterface** table) { for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); control->fTransportState = JackTransportStopped; control->fTransportSync = true; control->fTransportTimebase = true; jack_log("MakeAllLocating ref = %ld", i); } } } // RT void JackTransportEngine::CycleBegin(jack_nframes_t frame_rate, jack_time_t time) { jack_position_t* pending = WriteNextStateStart(1); // Update "pending" state pending->usecs = time; pending->frame_rate = frame_rate; WriteNextStateStop(1); } // RT void JackTransportEngine::CycleEnd(JackClientInterface** table, jack_nframes_t frame_rate, jack_nframes_t buffer_size) { TrySwitchState(1); // Switch from "pending" to "current", it always works since there is always a pending state /* Handle any new transport command from the last cycle. */ transport_command_t cmd = fTransportCmd; if (cmd != fPreviousCmd) { fPreviousCmd = cmd; jack_log("transport command: %s", (cmd == TransportCommandStart ? "Transport start" : "Transport stop")); } else { cmd = TransportCommandNone; } /* state transition switch */ switch (fTransportState) { case JackTransportStopped: // Set a JackTransportStarting for the current cycle, if all clients are ready (no slow_sync) ==> JackTransportRolling next state if (cmd == TransportCommandStart) { jack_log("transport stopped ==> starting frame = %d", ReadCurrentState()->frame); fTransportState = JackTransportStarting; MakeAllStartingLocating(table); SyncTimeout(frame_rate, buffer_size); } else if (fPendingPos) { jack_log("transport stopped ==> stopped (locating) frame = %d", ReadCurrentState()->frame); MakeAllLocating(table); } break; case JackTransportStarting: if (cmd == TransportCommandStop) { jack_log("transport starting ==> stopped frame = %d", ReadCurrentState()->frame); fTransportState = JackTransportStopped; MakeAllStopping(table); } else if (fPendingPos) { jack_log("transport starting ==> starting frame = %d", ReadCurrentState()->frame); fTransportState = JackTransportStarting; MakeAllStartingLocating(table); SyncTimeout(frame_rate, buffer_size); } else if (--fSyncTimeLeft == 0 || CheckAllRolling(table)) { // Slow clients may still catch up if (fNetworkSync) { jack_log("transport starting ==> netstarting frame = %d"); fTransportState = JackTransportNetStarting; } else { jack_log("transport starting ==> rolling fSyncTimeLeft = %ld", fSyncTimeLeft); fTransportState = JackTransportRolling; } } break; case JackTransportRolling: if (cmd == TransportCommandStop) { jack_log("transport rolling ==> stopped"); fTransportState = JackTransportStopped; MakeAllStopping(table); } else if (fPendingPos) { jack_log("transport rolling ==> starting"); fTransportState = JackTransportStarting; MakeAllStartingLocating(table); SyncTimeout(frame_rate, buffer_size); } break; case JackTransportNetStarting: break; default: jack_error("Invalid JACK transport state: %d", fTransportState); } /* Update timebase, if needed. */ if (fTransportState == JackTransportRolling) { jack_position_t* pending = WriteNextStateStart(1); // Update "pending" state pending->frame += buffer_size; WriteNextStateStop(1); } /* See if an asynchronous position request arrived during the last cycle. */ jack_position_t* request = WriteNextStateStart(2, &fPendingPos); if (fPendingPos) { jack_log("New pos = %ld", request->frame); jack_position_t* pending = WriteNextStateStart(1); CopyPosition(request, pending); WriteNextStateStop(1); } } // Client void JackTransportEngine::ReadCurrentPos(jack_position_t* pos) { UInt16 next_index = GetCurrentIndex(); UInt16 cur_index; do { cur_index = next_index; memcpy(pos, ReadCurrentState(), sizeof(jack_position_t)); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read } void JackTransportEngine::RequestNewPos(jack_position_t* pos) { jack_position_t* request = WriteNextStateStart(2); pos->unique_1 = pos->unique_2 = GenerateUniqueID(); CopyPosition(pos, request); jack_log("RequestNewPos pos = %ld", pos->frame); WriteNextStateStop(2); } jack_transport_state_t JackTransportEngine::Query(jack_position_t* pos) { if (pos) ReadCurrentPos(pos); return GetState(); } jack_nframes_t JackTransportEngine::GetCurrentFrame() { jack_position_t pos; ReadCurrentPos(&pos); if (fTransportState == JackTransportRolling) { float usecs = GetMicroSeconds() - pos.usecs; jack_nframes_t elapsed = (jack_nframes_t)floor((((float) pos.frame_rate) / 1000000.0f) * usecs); return pos.frame + elapsed; } else { return pos.frame; } } // RT, client void JackTransportEngine::CopyPosition(jack_position_t* from, jack_position_t* to) { int tries = 0; long timeout = 1000; do { /* throttle the busy wait if we don't get the answer * very quickly. See comment above about this * design. */ if (tries > 10) { JackSleep(20); tries = 0; /* debug code to avoid system hangs... */ if (--timeout == 0) { jack_error("hung in loop copying position B"); abort(); } } *to = *from; tries++; } while (to->unique_1 != to->unique_2); } } // end of namespace 1.9.12~dfsg/common/JackAudioAdapterInterface.cpp0000644000000000000000000003463613214314510020324 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef __APPLE__ #include #endif #include "JackAudioAdapter.h" #ifndef MY_TARGET_OS_IPHONE #include "JackLibSampleRateResampler.h" #endif #include "JackTime.h" #include "JackError.h" #include namespace Jack { #ifdef JACK_MONITOR void MeasureTable::Write(int time1, int time2, float r1, float r2, int pos1, int pos2) { int pos = (++fCount) % TABLE_MAX; fTable[pos].time1 = time1; fTable[pos].time2 = time2; fTable[pos].r1 = r1; fTable[pos].r2 = r2; fTable[pos].pos1 = pos1; fTable[pos].pos2 = pos2; } void MeasureTable::Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize) { FILE* file = fopen("JackAudioAdapter.log", "w"); int max = (fCount) % TABLE_MAX - 1; for (int i = 1; i < max; i++) { fprintf(file, "%d \t %d \t %d \t %f \t %f \t %d \t %d \n", fTable[i].delta, fTable[i].time1, fTable[i].time2, fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2); } fclose(file); // No used for now // Adapter timing 1 file = fopen("AdapterTiming1.plot", "w"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"frames\"\n"); fprintf(file, "plot "); fprintf(file, "\"JackAudioAdapter.log\" using 2 title \"Ringbuffer error\" with lines,"); fprintf(file, "\"JackAudioAdapter.log\" using 3 title \"Ringbuffer error with timing correction\" with lines"); fprintf(file, "\n unset multiplot\n"); fprintf(file, "set output 'AdapterTiming1.svg\n"); fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"frames\"\n"); fprintf(file, "plot "); fprintf(file, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,"); fprintf(file, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines\n"); fprintf(file, "unset multiplot\n"); fprintf(file, "unset output\n"); fclose(file); // Adapter timing 2 file = fopen("AdapterTiming2.plot", "w"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"resampling ratio\"\n"); fprintf(file, "plot "); fprintf(file, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,"); fprintf(file, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); fprintf(file, "\n unset multiplot\n"); fprintf(file, "set output 'AdapterTiming2.svg\n"); fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"resampling ratio\"\n"); fprintf(file, "plot "); fprintf(file, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,"); fprintf(file, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines\n"); fprintf(file, "unset multiplot\n"); fprintf(file, "unset output\n"); fclose(file); // Adapter timing 3 file = fopen("AdapterTiming3.plot", "w"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"frames\"\n"); fprintf(file, "plot "); fprintf(file, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,"); fprintf(file, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); fprintf(file, "\n unset multiplot\n"); fprintf(file, "set output 'AdapterTiming3.svg\n"); fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"frames\"\n"); fprintf(file, "plot "); fprintf(file, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,"); fprintf(file, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines\n"); fprintf(file, "unset multiplot\n"); fprintf(file, "unset output\n"); fclose(file); } #endif void JackAudioAdapterInterface::GrowRingBufferSize() { fRingbufferCurSize *= 2; } void JackAudioAdapterInterface::AdaptRingBufferSize() { if (fHostBufferSize > fAdaptedBufferSize) { fRingbufferCurSize = 4 * fHostBufferSize; } else { fRingbufferCurSize = 4 * fAdaptedBufferSize; } } void JackAudioAdapterInterface::ResetRingBuffers() { if (fRingbufferCurSize > DEFAULT_RB_SIZE) { fRingbufferCurSize = DEFAULT_RB_SIZE; } for (int i = 0; i < fCaptureChannels; i++) { fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); } for (int i = 0; i < fPlaybackChannels; i++) { fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); } } void JackAudioAdapterInterface::Reset() { ResetRingBuffers(); fRunning = false; } #ifdef MY_TARGET_OS_IPHONE void JackAudioAdapterInterface::Create() {} #else void JackAudioAdapterInterface::Create() { //ringbuffers fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; if (fAdaptative) { AdaptRingBufferSize(); jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); } else { if (fRingbufferCurSize > DEFAULT_RB_SIZE) { fRingbufferCurSize = DEFAULT_RB_SIZE; } jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); } for (int i = 0; i < fCaptureChannels; i++ ) { fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality); fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); } for (int i = 0; i < fPlaybackChannels; i++ ) { fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality); fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); } if (fCaptureChannels > 0) { jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); } if (fPlaybackChannels > 0) { jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); } } #endif void JackAudioAdapterInterface::Destroy() { for (int i = 0; i < fCaptureChannels; i++) { delete(fCaptureRingBuffer[i]); } for (int i = 0; i < fPlaybackChannels; i++) { delete (fPlaybackRingBuffer[i]); } delete[] fCaptureRingBuffer; delete[] fPlaybackRingBuffer; } int JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames) { bool failure = false; fRunning = true; // Finer estimation of the position in the ringbuffer int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0; double ratio = 1; // TODO : done like this just to avoid crash when input only or output only... if (fCaptureChannels > 0) { ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); } else if (fPlaybackChannels > 0) { ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames); } #ifdef JACK_MONITOR if (fCaptureRingBuffer && fCaptureRingBuffer[0] != NULL) fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); #endif // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { fCaptureRingBuffer[i]->SetRatio(ratio); if (inputBuffer[i]) { if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) { failure = true; } } } for (int i = 0; i < fPlaybackChannels; i++) { fPlaybackRingBuffer[i]->SetRatio(1/ratio); if (outputBuffer[i]) { if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) { failure = true; } } } // Reset all ringbuffers in case of failure if (failure) { jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset"); if (fAdaptative) { GrowRingBufferSize(); jack_info("Ringbuffer size = %d frames", fRingbufferCurSize); } ResetRingBuffers(); return -1; } else { return 0; } } int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) { fPullAndPushTime = GetMicroSeconds(); if (!fRunning) { return 0; } int res = 0; // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { if (inputBuffer[i]) { if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) { res = -1; } } } for (int i = 0; i < fPlaybackChannels; i++) { if (outputBuffer[i]) { if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) { res = -1; } } } return res; } int JackAudioAdapterInterface::SetHostBufferSize(jack_nframes_t buffer_size) { fHostBufferSize = buffer_size; if (fAdaptative) { AdaptRingBufferSize(); } return 0; } int JackAudioAdapterInterface::SetAdaptedBufferSize(jack_nframes_t buffer_size) { fAdaptedBufferSize = buffer_size; if (fAdaptative) { AdaptRingBufferSize(); } return 0; } int JackAudioAdapterInterface::SetBufferSize(jack_nframes_t buffer_size) { SetHostBufferSize(buffer_size); SetAdaptedBufferSize(buffer_size); return 0; } int JackAudioAdapterInterface::SetHostSampleRate(jack_nframes_t sample_rate) { fHostSampleRate = sample_rate; fPIControler.Init(double(fHostSampleRate) / double(fAdaptedSampleRate)); return 0; } int JackAudioAdapterInterface::SetAdaptedSampleRate(jack_nframes_t sample_rate) { fAdaptedSampleRate = sample_rate; fPIControler.Init(double(fHostSampleRate) / double(fAdaptedSampleRate)); return 0; } int JackAudioAdapterInterface::SetSampleRate(jack_nframes_t sample_rate) { SetHostSampleRate(sample_rate); SetAdaptedSampleRate(sample_rate); return 0; } void JackAudioAdapterInterface::SetInputs(int inputs) { jack_log("JackAudioAdapterInterface::SetInputs %d", inputs); fCaptureChannels = inputs; } void JackAudioAdapterInterface::SetOutputs(int outputs) { jack_log("JackAudioAdapterInterface::SetOutputs %d", outputs); fPlaybackChannels = outputs; } int JackAudioAdapterInterface::GetInputs() { //jack_log("JackAudioAdapterInterface::GetInputs %d", fCaptureChannels); return fCaptureChannels; } int JackAudioAdapterInterface::GetOutputs() { //jack_log ("JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels); return fPlaybackChannels; } } // namespace 1.9.12~dfsg/common/JackLibSampleRateResampler.cpp0000644000000000000000000001467213214314510020476 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackLibSampleRateResampler.h" #include "JackError.h" namespace Jack { JackLibSampleRateResampler::JackLibSampleRateResampler() :JackResampler() { int error; fResampler = src_new(SRC_LINEAR, 1, &error); if (error != 0) { jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); } } JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality) :JackResampler() { switch (quality) { case 0: quality = SRC_LINEAR; break; case 1: quality = SRC_ZERO_ORDER_HOLD; break; case 2: quality = SRC_SINC_FASTEST; break; case 3: quality = SRC_SINC_MEDIUM_QUALITY; break; case 4: quality = SRC_SINC_BEST_QUALITY; break; default: quality = SRC_LINEAR; jack_error("Out of range resample quality"); break; } int error; fResampler = src_new(quality, 1, &error); if (error != 0) { jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); } } JackLibSampleRateResampler::~JackLibSampleRateResampler() { src_delete(fResampler); } void JackLibSampleRateResampler::Reset(unsigned int new_size) { JackResampler::Reset(new_size); src_reset(fResampler); } unsigned int JackLibSampleRateResampler::ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames) { jack_ringbuffer_data_t ring_buffer_data[2]; SRC_DATA src_data; unsigned int frames_to_write = frames; unsigned int written_frames = 0; int res; jack_ringbuffer_get_read_vector(fRingBuffer, ring_buffer_data); unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(jack_default_audio_sample_t); jack_log("Output available = %ld", available_frames); for (int j = 0; j < 2; j++) { if (ring_buffer_data[j].len > 0) { src_data.data_in = (jack_default_audio_sample_t*)ring_buffer_data[j].buf; src_data.data_out = &buffer[written_frames]; src_data.input_frames = ring_buffer_data[j].len / sizeof(jack_default_audio_sample_t); src_data.output_frames = frames_to_write; src_data.end_of_input = 0; src_data.src_ratio = fRatio; res = src_process(fResampler, &src_data); if (res != 0) { jack_error("JackLibSampleRateResampler::ReadResample ratio = %f err = %s", fRatio, src_strerror(res)); return 0; } frames_to_write -= src_data.output_frames_gen; written_frames += src_data.output_frames_gen; if ((src_data.input_frames_used == 0 || src_data.output_frames_gen == 0) && j == 0) { jack_log("Output : j = %d input_frames_used = %ld output_frames_gen = %ld frames1 = %lu frames2 = %lu" , j, src_data.input_frames_used, src_data.output_frames_gen, ring_buffer_data[0].len, ring_buffer_data[1].len); } jack_log("Output : j = %d input_frames_used = %ld output_frames_gen = %ld", j, src_data.input_frames_used, src_data.output_frames_gen); jack_ringbuffer_read_advance(fRingBuffer, src_data.input_frames_used * sizeof(jack_default_audio_sample_t)); } } if (written_frames < frames) { jack_error("Output available = %ld", available_frames); jack_error("JackLibSampleRateResampler::ReadResample error written_frames = %ld", written_frames); } return written_frames; } unsigned int JackLibSampleRateResampler::WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames) { jack_ringbuffer_data_t ring_buffer_data[2]; SRC_DATA src_data; unsigned int frames_to_read = frames; unsigned int read_frames = 0; int res; jack_ringbuffer_get_write_vector(fRingBuffer, ring_buffer_data); unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(jack_default_audio_sample_t); jack_log("Input available = %ld", available_frames); for (int j = 0; j < 2; j++) { if (ring_buffer_data[j].len > 0) { src_data.data_in = &buffer[read_frames]; src_data.data_out = (jack_default_audio_sample_t*)ring_buffer_data[j].buf; src_data.input_frames = frames_to_read; src_data.output_frames = (ring_buffer_data[j].len / sizeof(jack_default_audio_sample_t)); src_data.end_of_input = 0; src_data.src_ratio = fRatio; res = src_process(fResampler, &src_data); if (res != 0) { jack_error("JackLibSampleRateResampler::WriteResample ratio = %f err = %s", fRatio, src_strerror(res)); return 0; } frames_to_read -= src_data.input_frames_used; read_frames += src_data.input_frames_used; if ((src_data.input_frames_used == 0 || src_data.output_frames_gen == 0) && j == 0) { jack_log("Input : j = %d input_frames_used = %ld output_frames_gen = %ld frames1 = %lu frames2 = %lu" , j, src_data.input_frames_used, src_data.output_frames_gen, ring_buffer_data[0].len, ring_buffer_data[1].len); } jack_log("Input : j = %d input_frames_used = %ld output_frames_gen = %ld", j, src_data.input_frames_used, src_data.output_frames_gen); jack_ringbuffer_write_advance(fRingBuffer, src_data.output_frames_gen * sizeof(jack_default_audio_sample_t)); } } if (read_frames < frames) { jack_error("Input available = %ld", available_frames); jack_error("JackLibSampleRateResampler::WriteResample error read_frames = %ld", read_frames); } return read_frames; } } 1.9.12~dfsg/common/JackServerLaunch.h0000644000000000000000000000171313214314510016175 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2006 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackServerLaunch__ #define __JackServerLaunch__ #include "varargs.h" #include "types.h" int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status); #endif 1.9.12~dfsg/common/JackAPI.cpp0000644000000000000000000022416013214314510014543 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackClient.h" #include "JackError.h" #include "JackGraphManager.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackGlobals.h" #include "JackTime.h" #include "JackPortType.h" #include "JackMetadata.h" #include using namespace Jack; #ifdef __cplusplus extern "C" { #endif typedef void (*print_function)(const char*); typedef void *(*thread_routine)(void*); LIB_EXPORT const char* JACK_METADATA_PRETTY_NAME = "http://jackaudio.org/metadata/pretty-name"; LIB_EXPORT const char* JACK_METADATA_HARDWARE = "http://jackaudio.org/metadata/hardware"; LIB_EXPORT const char* JACK_METADATA_CONNECTED = "http://jackaudio.org/metadata/connected"; LIB_EXPORT const char* JACK_METADATA_PORT_GROUP = "http://jackaudio.org/metadata/port-group"; LIB_EXPORT const char* JACK_METADATA_ICON_SMALL = "http://jackaudio.org/metadata/icon-small"; LIB_EXPORT const char* JACK_METADATA_ICON_LARGE = "http://jackaudio.org/metadata/icon-large"; LIB_EXPORT void jack_get_version( int *major_ptr, int *minor_ptr, int *micro_ptr, int *proto_ptr); LIB_EXPORT const char* jack_get_version_string(); jack_client_t * jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t *status); LIB_EXPORT jack_client_t * jack_client_open(const char* client_name, jack_options_t options, jack_status_t *status, ...); LIB_EXPORT jack_client_t * jack_client_new(const char* client_name); LIB_EXPORT int jack_client_name_size(void); LIB_EXPORT char* jack_get_client_name(jack_client_t *client); LIB_EXPORT int jack_internal_client_new(const char* client_name, const char* load_name, const char* load_init); LIB_EXPORT void jack_internal_client_close(const char* client_name); LIB_EXPORT int jack_is_realtime(jack_client_t *client); LIB_EXPORT void jack_on_shutdown(jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg); LIB_EXPORT void jack_on_info_shutdown(jack_client_t *client, JackInfoShutdownCallback shutdown_callback, void *arg); LIB_EXPORT int jack_set_process_callback(jack_client_t *client, JackProcessCallback process_callback, void *arg); LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status); // new LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t*); LIB_EXPORT void jack_cycle_signal(jack_client_t*, int status); LIB_EXPORT int jack_set_process_thread(jack_client_t* client, JackThreadCallback fun, void *arg); LIB_EXPORT int jack_set_thread_init_callback(jack_client_t *client, JackThreadInitCallback thread_init_callback, void *arg); LIB_EXPORT int jack_set_freewheel_callback(jack_client_t *client, JackFreewheelCallback freewheel_callback, void *arg); LIB_EXPORT int jack_set_freewheel(jack_client_t* client, int onoff); LIB_EXPORT int jack_set_buffer_size(jack_client_t *client, jack_nframes_t nframes); LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t *client, JackBufferSizeCallback bufsize_callback, void *arg); LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t *client, JackSampleRateCallback srate_callback, void *arg); LIB_EXPORT int jack_set_client_registration_callback(jack_client_t *, JackClientRegistrationCallback registration_callback, void *arg); LIB_EXPORT int jack_set_port_registration_callback(jack_client_t *, JackPortRegistrationCallback registration_callback, void *arg); LIB_EXPORT int jack_set_port_connect_callback(jack_client_t *, JackPortConnectCallback connect_callback, void *arg); LIB_EXPORT int jack_set_port_rename_callback(jack_client_t *, JackPortRenameCallback rename_callback, void *arg); LIB_EXPORT int jack_set_graph_order_callback(jack_client_t *, JackGraphOrderCallback graph_callback, void *); LIB_EXPORT int jack_set_xrun_callback(jack_client_t *, JackXRunCallback xrun_callback, void *arg); LIB_EXPORT int jack_set_latency_callback(jack_client_t *client, JackLatencyCallback latency_callback, void *arg); LIB_EXPORT int jack_activate(jack_client_t *client); LIB_EXPORT int jack_deactivate(jack_client_t *client); LIB_EXPORT jack_port_t * jack_port_register(jack_client_t *client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size); LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *); LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t); LIB_EXPORT jack_uuid_t jack_port_uuid(const jack_port_t*); LIB_EXPORT const char* jack_port_name(const jack_port_t *port); LIB_EXPORT const char* jack_port_short_name(const jack_port_t *port); LIB_EXPORT int jack_port_flags(const jack_port_t *port); LIB_EXPORT const char* jack_port_type(const jack_port_t *port); LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port); LIB_EXPORT int jack_port_is_mine(const jack_client_t *, const jack_port_t *port); LIB_EXPORT int jack_port_connected(const jack_port_t *port); LIB_EXPORT int jack_port_connected_to(const jack_port_t *port, const char* port_name); LIB_EXPORT const char* * jack_port_get_connections(const jack_port_t *port); LIB_EXPORT const char* * jack_port_get_all_connections(const jack_client_t *client, const jack_port_t *port); LIB_EXPORT int jack_port_tie(jack_port_t *src, jack_port_t *dst); LIB_EXPORT int jack_port_untie(jack_port_t *port); // Old latency API LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t *port); LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t *, jack_port_t *port); LIB_EXPORT void jack_port_set_latency(jack_port_t *, jack_nframes_t); LIB_EXPORT int jack_recompute_total_latency(jack_client_t*, jack_port_t* port); // New latency API LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range); LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range); LIB_EXPORT int jack_recompute_total_latencies(jack_client_t*); LIB_EXPORT int jack_port_set_name(jack_port_t *port, const char* port_name); LIB_EXPORT int jack_port_rename(jack_client_t *client, jack_port_t *port, const char* port_name); LIB_EXPORT int jack_port_set_alias(jack_port_t *port, const char* alias); LIB_EXPORT int jack_port_unset_alias(jack_port_t *port, const char* alias); LIB_EXPORT int jack_port_get_aliases(const jack_port_t *port, char* const aliases[2]); LIB_EXPORT int jack_port_request_monitor(jack_port_t *port, int onoff); LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t *client, const char* port_name, int onoff); LIB_EXPORT int jack_port_ensure_monitor(jack_port_t *port, int onoff); LIB_EXPORT int jack_port_monitoring_input(jack_port_t *port); LIB_EXPORT int jack_connect(jack_client_t *, const char* source_port, const char* destination_port); LIB_EXPORT int jack_disconnect(jack_client_t *, const char* source_port, const char* destination_port); LIB_EXPORT int jack_port_disconnect(jack_client_t *, jack_port_t *); LIB_EXPORT int jack_port_name_size(void); LIB_EXPORT int jack_port_type_size(void); LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t *client, const char* port_type); LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t *); LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t *); LIB_EXPORT const char* * jack_get_ports(jack_client_t *, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags); LIB_EXPORT jack_port_t * jack_port_by_name(jack_client_t *, const char* port_name); LIB_EXPORT jack_port_t * jack_port_by_id(jack_client_t *client, jack_port_id_t port_id); LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t *); LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t *); LIB_EXPORT jack_time_t jack_get_time(); LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t usecs); LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames); LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t *); LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t *client); LIB_EXPORT int jack_get_cycle_times(const jack_client_t *client, jack_nframes_t *current_frames, jack_time_t *current_usecs, jack_time_t *next_usecs, float *period_usecs); LIB_EXPORT float jack_cpu_load(jack_client_t *client); LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t *); LIB_EXPORT void jack_set_error_function(print_function); LIB_EXPORT void jack_set_info_function(print_function); LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t *client); LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t *client); LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t *client); LIB_EXPORT int jack_release_timebase(jack_client_t *client); LIB_EXPORT int jack_set_sync_callback(jack_client_t *client, JackSyncCallback sync_callback, void *arg); LIB_EXPORT int jack_set_sync_timeout(jack_client_t *client, jack_time_t timeout); LIB_EXPORT int jack_set_timebase_callback(jack_client_t *client, int conditional, JackTimebaseCallback timebase_callback, void *arg); LIB_EXPORT int jack_transport_locate(jack_client_t *client, jack_nframes_t frame); LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t *client, jack_position_t *pos); LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t *client); LIB_EXPORT int jack_transport_reposition(jack_client_t *client, const jack_position_t *pos); LIB_EXPORT void jack_transport_start(jack_client_t *client); LIB_EXPORT void jack_transport_stop(jack_client_t *client); LIB_EXPORT void jack_get_transport_info(jack_client_t *client, jack_transport_info_t *tinfo); LIB_EXPORT void jack_set_transport_info(jack_client_t *client, jack_transport_info_t *tinfo); LIB_EXPORT int jack_client_real_time_priority(jack_client_t*); LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t*); LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority); LIB_EXPORT int jack_client_create_thread(jack_client_t* client, jack_native_thread_t *thread, int priority, int realtime, // boolean thread_routine routine, void *arg); LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread); LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread); LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread); #ifndef WIN32 LIB_EXPORT void jack_set_thread_creator(jack_thread_creator_t jtc); #endif LIB_EXPORT char * jack_get_internal_client_name(jack_client_t *client, jack_intclient_t intclient); LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t *client, const char* client_name, jack_status_t *status); LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char* client_name, jack_options_t options, jack_status_t *status, ...); LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t *client, jack_intclient_t intclient); LIB_EXPORT void jack_free(void* ptr); LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg); LIB_EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path); LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event); LIB_EXPORT void jack_session_event_free(jack_session_event_t* ev); LIB_EXPORT char* jack_client_get_uuid (jack_client_t *client); LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name); LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid); LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* name, const char* uuid); LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds); LIB_EXPORT int jack_client_has_session_callback(jack_client_t *client, const char* client_name); LIB_EXPORT int jack_set_property(jack_client_t*, jack_uuid_t subject, const char* key, const char* value, const char* type); LIB_EXPORT int jack_get_property(jack_uuid_t subject, const char* key, char** value, char** type); LIB_EXPORT void jack_free_description(jack_description_t* desc, int free_description_itself); LIB_EXPORT int jack_get_properties(jack_uuid_t subject, jack_description_t* desc); LIB_EXPORT int jack_get_all_properties(jack_description_t** descs); LIB_EXPORT int jack_remove_property(jack_client_t* client, jack_uuid_t subject, const char* key); LIB_EXPORT int jack_remove_properties(jack_client_t* client, jack_uuid_t subject); LIB_EXPORT int jack_remove_all_properties(jack_client_t* client); LIB_EXPORT int jack_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg); LIB_EXPORT jack_uuid_t jack_client_uuid_generate(); LIB_EXPORT jack_uuid_t jack_port_uuid_generate(uint32_t port_id); LIB_EXPORT uint32_t jack_uuid_to_index(jack_uuid_t); LIB_EXPORT int jack_uuid_compare(jack_uuid_t, jack_uuid_t); LIB_EXPORT void jack_uuid_copy(jack_uuid_t* dst, jack_uuid_t src); LIB_EXPORT void jack_uuid_clear(jack_uuid_t*); LIB_EXPORT int jack_uuid_parse(const char* buf, jack_uuid_t*); LIB_EXPORT void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]); LIB_EXPORT int jack_uuid_empty(jack_uuid_t); #ifdef __cplusplus } #endif static inline bool CheckPort(jack_port_id_t port_index) { return (port_index > 0 && port_index < PORT_NUM_MAX); } static inline bool CheckBufferSize(jack_nframes_t buffer_size) { return (buffer_size >= 1 && buffer_size <= BUFFER_SIZE_MAX); } static inline void WaitGraphChange() { /* TLS key that is set only in RT thread, so never waits for pending graph change in RT context (just read the current graph state). */ if (jack_tls_get(JackGlobals::fRealTimeThread) == NULL) { JackGraphManager* manager = GetGraphManager(); JackEngineControl* control = GetEngineControl(); assert(manager); assert(control); if (manager->IsPendingChange()) { jack_log("WaitGraphChange..."); JackSleep(int(control->fPeriodUsecs * 1.1f)); } } } LIB_EXPORT void jack_set_error_function(print_function func) { jack_error_callback = (func == NULL) ? &default_jack_error_callback : func; } LIB_EXPORT void jack_set_info_function(print_function func) { jack_info_callback = (func == NULL) ? &default_jack_info_callback : func; } LIB_EXPORT jack_client_t* jack_client_new(const char* client_name) { JackGlobals::CheckContext("jack_client_new"); try { assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); jack_error("jack_client_new: deprecated"); int options = JackUseExactName; if (getenv("JACK_START_SERVER") == NULL) { options |= JackNoStartServer; } jack_client_t* res = jack_client_new_aux(client_name, (jack_options_t)options, NULL); JackGlobals::fOpenMutex->Unlock(); return res; } catch (std::bad_alloc& e) { jack_error("Memory allocation error..."); return NULL; } catch (...) { jack_error("Unknown error..."); return NULL; } } LIB_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) { JackGlobals::CheckContext("jack_port_get_buffer"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_buffer called with an incorrect port %ld", myport); return NULL; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetBuffer(myport, frames) : NULL); } } LIB_EXPORT jack_uuid_t jack_port_uuid(const jack_port_t*) { return 0; } LIB_EXPORT const char* jack_port_name(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_name"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_name called with an incorrect port %ld", myport); return NULL; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->GetName() : NULL); } } LIB_EXPORT const char* jack_port_short_name(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_short_name"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_short_name called with an incorrect port %ld", myport); return NULL; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->GetShortName() : NULL); } } LIB_EXPORT int jack_port_flags(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_flags"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_flags called with an incorrect port %ld", myport); return -1; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->GetFlags() : -1); } } LIB_EXPORT const char* jack_port_type(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_type"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_flags called an incorrect port %ld", myport); return NULL; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->GetType() : NULL); } } LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port) { JackGlobals::CheckContext("jack_port_type_id"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_type_id called an incorrect port %ld", myport); return 0; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0); } } LIB_EXPORT int jack_port_connected(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_connected"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_connected called with an incorrect port %ld", myport); return -1; } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetConnectionsNum(myport) : -1); } } LIB_EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name) { JackGlobals::CheckContext("jack_port_connected_to"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t src = (jack_port_id_t)port_aux; if (!CheckPort(src)) { jack_error("jack_port_connected_to called with an incorrect port %ld", src); return -1; } else if (port_name == NULL) { jack_error("jack_port_connected_to called with a NULL port name"); return -1; } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); jack_port_id_t dst = (manager ? manager->GetPort(port_name) : NO_PORT); if (dst == NO_PORT) { jack_error("Unknown destination port port_name = %s", port_name); return 0; } else { return manager->IsConnected(src, dst); } } } LIB_EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst) { JackGlobals::CheckContext("jack_port_tie"); uintptr_t src_aux = (uintptr_t)src; jack_port_id_t mysrc = (jack_port_id_t)src_aux; if (!CheckPort(mysrc)) { jack_error("jack_port_tie called with a NULL src port"); return -1; } uintptr_t dst_aux = (uintptr_t)dst; jack_port_id_t mydst = (jack_port_id_t)dst_aux; if (!CheckPort(mydst)) { jack_error("jack_port_tie called with a NULL dst port"); return -1; } JackGraphManager* manager = GetGraphManager(); if (manager && manager->GetPort(mysrc)->GetRefNum() != manager->GetPort(mydst)->GetRefNum()) { jack_error("jack_port_tie called with ports not belonging to the same client"); return -1; } else { return manager->GetPort(mydst)->Tie(mysrc); } } LIB_EXPORT int jack_port_untie(jack_port_t* port) { JackGlobals::CheckContext("jack_port_untie"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_untie called with an incorrect port %ld", myport); return -1; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->UnTie() : -1); } } LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port) { JackGlobals::CheckContext("jack_port_get_latency"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_latency called with an incorrect port %ld", myport); return 0; } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->GetLatency() : 0); } } LIB_EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) { JackGlobals::CheckContext("jack_port_set_latency"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_set_latency called with an incorrect port %ld", myport); } else { JackGraphManager* manager = GetGraphManager(); if (manager) manager->GetPort(myport)->SetLatency(frames); } } LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) { JackGlobals::CheckContext("jack_port_get_latency_range"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_latency_range called with an incorrect port %ld", myport); } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); if (manager) manager->GetPort(myport)->GetLatencyRange(mode, range); } } LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) { JackGlobals::CheckContext("jack_port_set_latency_range"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_set_latency_range called with an incorrect port %ld", myport); } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); if (manager) manager->GetPort(myport)->SetLatencyRange(mode, range); } } LIB_EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port) { JackGlobals::CheckContext("jack_recompute_total_latency"); JackClient* client = (JackClient*)ext_client; uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (client == NULL) { jack_error("jack_recompute_total_latency called with a NULL client"); return -1; } else if (!CheckPort(myport)) { jack_error("jack_recompute_total_latency called with a NULL port"); return -1; } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); return (manager ? manager->ComputeTotalLatency(myport) : -1); } } LIB_EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_recompute_total_latencies"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_recompute_total_latencies called with a NULL client"); return -1; } else { return client->ComputeTotalLatencies(); } } LIB_EXPORT int jack_port_set_name(jack_port_t* port, const char* name) { JackGlobals::CheckContext("jack_port_set_name"); jack_error("jack_port_set_name: deprecated"); // Find a valid client jack_client_t* client = NULL; for (int i = 0; i < CLIENT_NUM; i++) { if ((client = (jack_client_t*)JackGlobals::fClientTable[i])) { break; } } return (client) ? jack_port_rename(client, port, name) : -1; } LIB_EXPORT int jack_port_rename(jack_client_t* ext_client, jack_port_t* port, const char* name) { JackGlobals::CheckContext("jack_port_rename"); JackClient* client = (JackClient*)ext_client; uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (client == NULL) { jack_error("jack_port_rename called with a NULL client"); return -1; } else if (!CheckPort(myport)) { jack_error("jack_port_rename called with an incorrect port %ld", myport); return -1; } else if (name == NULL) { jack_error("jack_port_rename called with a NULL port name"); return -1; } else { return client->PortRename(myport, name); } } LIB_EXPORT int jack_port_set_alias(jack_port_t* port, const char* name) { JackGlobals::CheckContext("jack_port_set_alias"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_set_alias called with an incorrect port %ld", myport); return -1; } else if (name == NULL) { jack_error("jack_port_set_alias called with a NULL port name"); return -1; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->SetAlias(name) : -1); } } LIB_EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name) { JackGlobals::CheckContext("jack_port_unset_alias"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_unset_alias called with an incorrect port %ld", myport); return -1; } else if (name == NULL) { jack_error("jack_port_unset_alias called with a NULL port name"); return -1; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->UnsetAlias(name) : -1); } } LIB_EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2]) { JackGlobals::CheckContext("jack_port_get_aliases"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_aliases called with an incorrect port %ld", myport); return -1; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->GetAliases(aliases) : -1); } } LIB_EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff) { JackGlobals::CheckContext("jack_port_request_monitor"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_request_monitor called with an incorrect port %ld", myport); return -1; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->RequestMonitor(myport, onoff) : -1); } } LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff) { JackGlobals::CheckContext("jack_port_request_monitor_by_name"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_request_monitor_by_name called with a NULL client"); return -1; } else { JackGraphManager* manager = GetGraphManager(); if (!manager) return -1; jack_port_id_t myport = manager->GetPort(port_name); if (!CheckPort(myport)) { jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name); return -1; } else { return manager->RequestMonitor(myport, onoff); } } } LIB_EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff) { JackGlobals::CheckContext("jack_port_ensure_monitor"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport); return -1; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->EnsureMonitor(onoff) : -1); } } LIB_EXPORT int jack_port_monitoring_input(jack_port_t* port) { JackGlobals::CheckContext("jack_port_monitoring_input"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport); return -1; } else { JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPort(myport)->MonitoringInput() : -1); } } LIB_EXPORT int jack_is_realtime(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_is_realtime"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_is_realtime called with a NULL client"); return -1; } else { JackEngineControl* control = GetEngineControl(); return (control ? control->fRealTime : -1); } } LIB_EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback callback, void* arg) { JackGlobals::CheckContext("jack_on_shutdown"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_on_shutdown called with a NULL client"); } else { client->OnShutdown(callback, arg); } } LIB_EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg) { JackGlobals::CheckContext("jack_on_info_shutdown"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_on_info_shutdown called with a NULL client"); } else { client->OnInfoShutdown(callback, arg); } } LIB_EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg) { JackGlobals::CheckContext("jack_set_process_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_process_callback called with a NULL client"); return -1; } else { return client->SetProcessCallback(callback, arg); } } LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status) { JackGlobals::CheckContext("jack_thread_wait"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_thread_wait called with a NULL client"); return 0; } else { jack_error("jack_thread_wait: deprecated, use jack_cycle_wait/jack_cycle_signal"); return 0; } } LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_cycle_wait"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_cycle_wait called with a NULL client"); return 0; } else { return client->CycleWait(); } } LIB_EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status) { JackGlobals::CheckContext("jack_cycle_signal"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_cycle_signal called with a NULL client"); } else { client->CycleSignal(status); } } LIB_EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg) { JackGlobals::CheckContext("jack_set_process_thread"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_process_thread called with a NULL client"); return -1; } else { return client->SetProcessThread(fun, arg); } } LIB_EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg) { JackGlobals::CheckContext("jack_set_freewheel_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_freewheel_callback called with a NULL client"); return -1; } else { return client->SetFreewheelCallback(freewheel_callback, arg); } } LIB_EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff) { JackGlobals::CheckContext("jack_set_freewheel"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_freewheel called with a NULL client"); return -1; } else { return client->SetFreeWheel(onoff); } } LIB_EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size) { JackGlobals::CheckContext("jack_set_buffer_size"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_buffer_size called with a NULL client"); return -1; } else if (!CheckBufferSize(buffer_size)) { return -1; } else { return client->SetBufferSize(buffer_size); } } LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg) { JackGlobals::CheckContext("jack_set_buffer_size_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_buffer_size_callback called with a NULL client"); return -1; } else { return client->SetBufferSizeCallback(bufsize_callback, arg); } } LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg) { JackGlobals::CheckContext("jack_set_sample_rate_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_sample_rate_callback called with a NULL client"); return -1; } else { return client->SetSampleRateCallback(srate_callback, arg); } } LIB_EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg) { JackGlobals::CheckContext("jack_set_client_registration_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_client_registration_callback called with a NULL client"); return -1; } else { return client->SetClientRegistrationCallback(registration_callback, arg); } } LIB_EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg) { JackGlobals::CheckContext("jack_set_port_registration_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_port_registration_callback called with a NULL client"); return -1; } else { return client->SetPortRegistrationCallback(registration_callback, arg); } } LIB_EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg) { JackGlobals::CheckContext("jack_set_port_connect_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_port_connect_callback called with a NULL client"); return -1; } else { return client->SetPortConnectCallback(portconnect_callback, arg); } } LIB_EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRenameCallback rename_callback, void* arg) { JackGlobals::CheckContext("jack_set_port_rename_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_port_rename_callback called with a NULL client"); return -1; } else { return client->SetPortRenameCallback(rename_callback, arg); } } LIB_EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg) { JackGlobals::CheckContext("jack_set_graph_order_callback"); JackClient* client = (JackClient*)ext_client; jack_log("jack_set_graph_order_callback ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_set_graph_order_callback called with a NULL client"); return -1; } else { return client->SetGraphOrderCallback(graph_callback, arg); } } LIB_EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg) { JackGlobals::CheckContext("jack_set_xrun_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_xrun_callback called with a NULL client"); return -1; } else { return client->SetXRunCallback(xrun_callback, arg); } } LIB_EXPORT int jack_set_latency_callback(jack_client_t* ext_client, JackLatencyCallback latency_callback, void *arg) { JackGlobals::CheckContext("jack_set_latency_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_latency_callback called with a NULL client"); return -1; } else { return client->SetLatencyCallback(latency_callback, arg); } } LIB_EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg) { JackGlobals::CheckContext("jack_set_thread_init_callback"); JackClient* client = (JackClient*)ext_client; jack_log("jack_set_thread_init_callback ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_set_thread_init_callback called with a NULL client"); return -1; } else { return client->SetInitCallback(init_callback, arg); } } LIB_EXPORT int jack_activate(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_activate"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_activate called with a NULL client"); return -1; } else { return client->Activate(); } } LIB_EXPORT int jack_deactivate(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_deactivate"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_deactivate called with a NULL client"); return -1; } else { return client->Deactivate(); } } LIB_EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size) { JackGlobals::CheckContext("jack_port_register"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_register called with a NULL client"); return NULL; } else if ((port_name == NULL) || (port_type == NULL)) { jack_error("jack_port_register called with a NULL port name or a NULL port_type"); return NULL; } else { return (jack_port_t *)((uintptr_t)client->PortRegister(port_name, port_type, flags, buffer_size)); } } LIB_EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port) { JackGlobals::CheckContext("jack_port_unregister"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_unregister called with a NULL client"); return -1; } uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_unregister called with an incorrect port %ld", myport); return -1; } return client->PortUnRegister(myport); } LIB_EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port) { JackGlobals::CheckContext("jack_port_is_mine"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_is_mine called with a NULL client"); return -1; } uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_is_mine called with an incorrect port %ld", myport); return -1; } return client->PortIsMine(myport); } LIB_EXPORT const char** jack_port_get_connections(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_get_connections"); uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_connections called with an incorrect port %ld", myport); return NULL; } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetConnections(myport) : NULL); } } // Calling client does not need to "own" the port LIB_EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port) { JackGlobals::CheckContext("jack_port_get_all_connections"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_get_all_connections called with a NULL client"); return NULL; } uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport); return NULL; } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetConnections(myport) : NULL); } } LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port) { JackGlobals::CheckContext("jack_port_get_total_latency"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_get_total_latency called with a NULL client"); return 0; } uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport); return 0; } else { WaitGraphChange(); JackGraphManager* manager = GetGraphManager(); if (manager) { manager->ComputeTotalLatency(myport); return manager->GetPort(myport)->GetTotalLatency(); } else { return 0; } } } LIB_EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst) { JackGlobals::CheckContext("jack_connect"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_connect called with a NULL client"); return -1; } else if ((src == NULL) || (dst == NULL)) { jack_error("jack_connect called with a NULL port name"); return -1; } else { return client->PortConnect(src, dst); } } LIB_EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst) { JackGlobals::CheckContext("jack_disconnect"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_disconnect called with a NULL client"); return -1; } else if ((src == NULL) || (dst == NULL)) { jack_error("jack_disconnect called with a NULL port name"); return -1; } else { return client->PortDisconnect(src, dst); } } LIB_EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src) { JackGlobals::CheckContext("jack_port_disconnect"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_disconnect called with a NULL client"); return -1; } uintptr_t port_aux = (uintptr_t)src; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_disconnect called with an incorrect port %ld", myport); return -1; } return client->PortDisconnect(myport); } LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_get_sample_rate"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_get_sample_rate called with a NULL client"); return 0; } else { JackEngineControl* control = GetEngineControl(); return (control ? control->fSampleRate : 0); } } LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_get_buffer_size"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_get_buffer_size called with a NULL client"); return 0; } else { JackEngineControl* control = GetEngineControl(); return (control ? control->fBufferSize : 0); } } LIB_EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags) { JackGlobals::CheckContext("jack_get_ports"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_get_ports called with a NULL client"); return NULL; } JackGraphManager* manager = GetGraphManager(); return (manager ? manager->GetPorts(port_name_pattern, type_name_pattern, flags) : NULL); } LIB_EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname) { JackGlobals::CheckContext("jack_port_by_name"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_by_name called with a NULL client"); return NULL; } if (portname == NULL) { jack_error("jack_port_by_name called with a NULL port name"); return NULL; } JackGraphManager* manager = GetGraphManager(); if (manager) { int res = manager->GetPort(portname); // returns a port index at least > 1 return (res == NO_PORT) ? NULL : (jack_port_t*)((uintptr_t)res); } else { return NULL; } } LIB_EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id) { JackGlobals::CheckContext("jack_port_by_id"); /* jack_port_t* type is actually the port index */ return (jack_port_t*)((uintptr_t)id); } LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_engine_takeover_timebase"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_engine_takeover_timebase called with a NULL client"); return -1; } else { jack_error("jack_engine_takeover_timebase: deprecated\n"); return 0; } } LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client) { JackGlobals::CheckContext("jack_frames_since_cycle_start"); JackTimer timer; JackEngineControl* control = GetEngineControl(); if (control) { control->ReadFrameTime(&timer); return timer.FramesSinceCycleStart(GetMicroSeconds(), control->fSampleRate); } else { return 0; } } LIB_EXPORT jack_time_t jack_get_time() { JackGlobals::CheckContext("jack_get_time"); return GetMicroSeconds(); } LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames) { JackGlobals::CheckContext("jack_frames_to_time"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_frames_to_time called with a NULL client"); return 0; } else { JackTimer timer; JackEngineControl* control = GetEngineControl(); if (control) { control->ReadFrameTime(&timer); return timer.Frames2Time(frames, control->fBufferSize); } else { return 0; } } } LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t usecs) { JackGlobals::CheckContext("jack_time_to_frames"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_time_to_frames called with a NULL client"); return 0; } else { JackTimer timer; JackEngineControl* control = GetEngineControl(); if (control) { control->ReadFrameTime(&timer); return timer.Time2Frames(usecs, control->fBufferSize); } else { return 0; } } } LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client) { JackGlobals::CheckContext("jack_frame_time"); return jack_time_to_frames(ext_client, GetMicroSeconds()); } LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) { JackGlobals::CheckContext("jack_last_frame_time"); JackEngineControl* control = GetEngineControl(); return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0; } LIB_EXPORT int jack_get_cycle_times(const jack_client_t *client, jack_nframes_t *current_frames, jack_time_t *current_usecs, jack_time_t *next_usecs, float *period_usecs) { JackGlobals::CheckContext("jack_get_cycle_times"); JackEngineControl* control = GetEngineControl(); if (control) { JackTimer timer; control->ReadFrameTime(&timer); return timer.GetCycleTimes(current_frames, current_usecs, next_usecs, period_usecs); } else { return -1; } } LIB_EXPORT float jack_cpu_load(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_cpu_load"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_cpu_load called with a NULL client"); return 0.0f; } else { JackEngineControl* control = GetEngineControl(); return (control ? control->fCPULoad : 0.0f); } } LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_client_thread_id"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_client_thread_id called with a NULL client"); return (jack_native_thread_t)NULL; } else { return client->GetThreadID(); } } LIB_EXPORT char* jack_get_client_name(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_get_client_name"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_get_client_name called with a NULL client"); return NULL; } else { return client->GetClientControl()->fName; } } LIB_EXPORT int jack_client_name_size(void) { return JACK_CLIENT_NAME_SIZE+1; } LIB_EXPORT int jack_port_name_size(void) { return REAL_JACK_PORT_NAME_SIZE+1; } LIB_EXPORT int jack_port_type_size(void) { return JACK_PORT_TYPE_SIZE; } LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t* ext_client, const char* port_type) { JackGlobals::CheckContext("jack_port_type_get_buffer_size"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_port_type_get_buffer_size called with a NULL client"); return 0; } else { jack_port_type_id_t port_id = GetPortTypeId(port_type); if (port_id == PORT_TYPES_MAX) { jack_error("jack_port_type_get_buffer_size called with an unknown port type = %s", port_type); return 0; } else { return GetPortType(port_id)->size(); } } } // transport.h LIB_EXPORT int jack_release_timebase(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_release_timebase"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_release_timebase called with a NULL client"); return -1; } else { return client->ReleaseTimebase(); } } LIB_EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg) { JackGlobals::CheckContext("jack_set_sync_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_sync_callback called with a NULL client"); return -1; } else { return client->SetSyncCallback(sync_callback, arg); } } LIB_EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout) { JackGlobals::CheckContext("jack_set_sync_timeout"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_sync_timeout called with a NULL client"); return -1; } else { return client->SetSyncTimeout(timeout); } } LIB_EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg) { JackGlobals::CheckContext("jack_set_timebase_callback"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_set_timebase_callback called with a NULL client"); return -1; } else { return client->SetTimebaseCallback(conditional, timebase_callback, arg); } } LIB_EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame) { JackGlobals::CheckContext("jack_transport_locate"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_transport_locate called with a NULL client"); return -1; } else { client->TransportLocate(frame); return 0; } } LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos) { JackGlobals::CheckContext("jack_transport_query"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_transport_query called with a NULL client"); return JackTransportStopped; } else { return client->TransportQuery(pos); } } LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client) { JackGlobals::CheckContext("jack_get_current_transport_frame"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_get_current_transport_frame called with a NULL client"); return 0; } else { return client->GetCurrentTransportFrame(); } } LIB_EXPORT int jack_transport_reposition(jack_client_t* ext_client, const jack_position_t* pos) { JackGlobals::CheckContext("jack_transport_reposition"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_transport_reposition called with a NULL client"); return -1; } else { client->TransportReposition(pos); return 0; } } LIB_EXPORT void jack_transport_start(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_transport_start"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_transport_start called with a NULL client"); } else { client->TransportStart(); } } LIB_EXPORT void jack_transport_stop(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_transport_stop"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_transport_stop called with a NULL client"); } else { client->TransportStop(); } } // deprecated LIB_EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo) { JackGlobals::CheckContext("jack_get_transport_info"); jack_error("jack_get_transport_info: deprecated"); if (tinfo) memset(tinfo, 0, sizeof(jack_transport_info_t)); } LIB_EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo) { JackGlobals::CheckContext("jack_set_transport_info"); jack_error("jack_set_transport_info: deprecated"); if (tinfo) memset(tinfo, 0, sizeof(jack_transport_info_t)); } // statistics.h LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_get_max_delayed_usecs"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_get_max_delayed_usecs called with a NULL client"); return 0.f; } else { JackEngineControl* control = GetEngineControl(); return (control ? control->fMaxDelayedUsecs : 0.f); } } LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_get_xrun_delayed_usecs"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_get_xrun_delayed_usecs called with a NULL client"); return 0.f; } else { JackEngineControl* control = GetEngineControl(); return (control ? control->fXrunDelayedUsecs : 0.f); } } LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_reset_max_delayed_usecs"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_reset_max_delayed_usecs called with a NULL client"); } else { JackEngineControl* control = GetEngineControl(); control->ResetXRun(); } } // thread.h LIB_EXPORT int jack_client_real_time_priority(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_client_real_time_priority"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_client_real_time_priority called with a NULL client"); return -1; } else { JackEngineControl* control = GetEngineControl(); return (control->fRealTime) ? control->fClientPriority : -1; } } LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_client_max_real_time_priority"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_client_max_real_time_priority called with a NULL client"); return -1; } else { JackEngineControl* control = GetEngineControl(); return (control->fRealTime) ? control->fMaxClientPriority : -1; } } LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority) { JackEngineControl* control = GetEngineControl(); return (control ? JackThread::AcquireRealTimeImp(thread, priority, control->fPeriod, control->fComputation, control->fConstraint) : -1); } LIB_EXPORT int jack_client_create_thread(jack_client_t* client, jack_native_thread_t *thread, int priority, int realtime, /* boolean */ thread_routine routine, void *arg) { JackGlobals::CheckContext("jack_client_create_thread"); JackEngineControl* control = GetEngineControl(); int res = JackThread::StartImp(thread, priority, realtime, routine, arg); return (res == 0) ? ((realtime ? JackThread::AcquireRealTimeImp(*thread, priority, control->fPeriod, control->fComputation, control->fConstraint) : res)) : res; } LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread) { return JackThread::DropRealTimeImp(thread); } LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread) { JackGlobals::CheckContext("jack_client_stop_thread"); return JackThread::StopImp(thread); } LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread) { JackGlobals::CheckContext("jack_client_kill_thread"); return JackThread::KillImp(thread); } #ifndef WIN32 LIB_EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc) { if (jtc == NULL) { JackGlobals::fJackThreadCreator = pthread_create; } else { JackGlobals::fJackThreadCreator = jtc; } } #endif // intclient.h LIB_EXPORT int jack_internal_client_new (const char* client_name, const char* load_name, const char* load_init) { JackGlobals::CheckContext("jack_internal_client_new"); jack_error("jack_internal_client_new: deprecated"); return -1; } LIB_EXPORT void jack_internal_client_close (const char* client_name) { JackGlobals::CheckContext("jack_internal_client_close"); jack_error("jack_internal_client_close: deprecated"); } LIB_EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient) { JackGlobals::CheckContext("jack_get_internal_client_name"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_get_internal_client_name called with a NULL client"); return NULL; } else if (intclient >= CLIENT_NUM) { jack_error("jack_get_internal_client_name: incorrect client"); return NULL; } else { return client->GetInternalClientName(intclient); } } LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status) { JackGlobals::CheckContext("jack_internal_client_handle"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_internal_client_handle called with a NULL client"); return 0; } else { jack_status_t my_status; if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ *status = (jack_status_t)0; return client->InternalClientHandle(client_name, status); } } static jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) { JackGlobals::CheckContext("jack_internal_client_load_aux"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_internal_client_load called with a NULL client"); return 0; } else { jack_varargs_t va; jack_status_t my_status; if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ *status = (jack_status_t)0; /* validate parameters */ if ((options & ~JackLoadOptions)) { int my_status1 = *status | (JackFailure | JackInvalidOption); *status = (jack_status_t)my_status1; return 0; } /* parse variable arguments */ jack_varargs_parse(options, ap, &va); return client->InternalClientLoad(client_name, options, status, &va); } } LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char* client_name, jack_options_t options, jack_status_t *status, ...) { JackGlobals::CheckContext("jack_internal_client_load"); va_list ap; va_start(ap, status); jack_intclient_t res = jack_internal_client_load_aux(client, client_name, options, status, ap); va_end(ap); return res; } LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient) { JackGlobals::CheckContext("jack_internal_client_load"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_internal_client_unload called with a NULL client"); return (jack_status_t)(JackNoSuchClient | JackFailure); } else if (intclient >= CLIENT_NUM) { jack_error("jack_internal_client_unload: incorrect client"); return (jack_status_t)(JackNoSuchClient | JackFailure); } else { jack_status_t my_status; client->InternalClientUnload(intclient, &my_status); return my_status; } } LIB_EXPORT void jack_get_version(int *major_ptr, int *minor_ptr, int *micro_ptr, int *proto_ptr) { JackGlobals::CheckContext("jack_get_version"); // FIXME: We need these comming from build system *major_ptr = 0; *minor_ptr = 0; *micro_ptr = 0; *proto_ptr = 0; } LIB_EXPORT const char* jack_get_version_string() { JackGlobals::CheckContext("jack_get_version_string"); return VERSION; } LIB_EXPORT void jack_free(void* ptr) { JackGlobals::CheckContext("jack_free"); if (ptr) { free(ptr); } } // session.h LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg) { JackGlobals::CheckContext("jack_set_session_callback"); JackClient* client = (JackClient*)ext_client; jack_log("jack_set_session_callback ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_set_session_callback called with a NULL client"); return -1; } else { return client->SetSessionCallback(session_callback, arg); } } LIB_EXPORT jack_session_command_t* jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path) { JackGlobals::CheckContext("jack_session_notify"); JackClient* client = (JackClient*)ext_client; jack_log("jack_session_notify ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_session_notify called with a NULL client"); return NULL; } else { return client->SessionNotify(target, ev_type, path); } } LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event) { JackGlobals::CheckContext("jack_session_reply"); JackClient* client = (JackClient*)ext_client; jack_log("jack_session_reply ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_session_reply called with a NULL client"); return -1; } else { return client->SessionReply(event); } } LIB_EXPORT void jack_session_event_free(jack_session_event_t* ev) { JackGlobals::CheckContext("jack_session_event_free"); if (ev) { if (ev->session_dir) free((void *)ev->session_dir); if (ev->client_uuid) free((void *)ev->client_uuid); if (ev->command_line) free(ev->command_line); free(ev); } } LIB_EXPORT char *jack_client_get_uuid(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_client_get_uuid"); JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_client_get_uuid called with a NULL client"); return NULL; } else { char retval[16]; snprintf(retval, sizeof(retval), "%d", client->GetClientControl()->fSessionID); return strdup(retval); } } LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name) { JackGlobals::CheckContext("jack_get_uuid_for_client_name"); JackClient* client = (JackClient*)ext_client; jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_get_uuid_for_client_name called with a NULL client"); return NULL; } else { return client->GetUUIDForClientName(client_name); } } LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid) { JackGlobals::CheckContext("jack_get_client_name_by_uuid"); JackClient* client = (JackClient*)ext_client; jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_get_client_name_by_uuid called with a NULL client"); return NULL; } else { return client->GetClientNameByUUID(client_uuid); } } LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* client_name, const char* uuid) { JackGlobals::CheckContext("jack_reserve_client_name"); JackClient* client = (JackClient*)ext_client; jack_log("jack_reserve_client_name ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_reserve_client_name called with a NULL client"); return -1; } else { return client->ReserveClientName(client_name, uuid); } } LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds) { JackGlobals::CheckContext("jack_session_commands_free"); if (!cmds) { return; } int i = 0; while (1) { if (cmds[i].client_name) { free ((char *)cmds[i].client_name); } if (cmds[i].command) { free ((char *)cmds[i].command); } if (cmds[i].uuid) { free ((char *)cmds[i].uuid); } else { break; } i += 1; } free(cmds); } LIB_EXPORT int jack_client_has_session_callback(jack_client_t* ext_client, const char* client_name) { JackGlobals::CheckContext("jack_client_has_session_callback"); JackClient* client = (JackClient*)ext_client; jack_log("jack_client_has_session_callback ext_client %x client %x ", ext_client, client); if (client == NULL) { jack_error("jack_client_has_session_callback called with a NULL client"); return -1; } else { return client->ClientHasSessionCallback(client_name); } } LIB_EXPORT int jack_set_property(jack_client_t*, jack_uuid_t, const char*, const char*, const char*) { return -1; } LIB_EXPORT int jack_get_property(jack_uuid_t, const char*, char**, char**) { return -1; } LIB_EXPORT void jack_free_description(jack_description_t*, int) { } LIB_EXPORT int jack_get_properties(jack_uuid_t, jack_description_t*) { return -1; } LIB_EXPORT int jack_get_all_properties(jack_description_t**) { return -1; } LIB_EXPORT int jack_remove_property(jack_client_t*, jack_uuid_t, const char*) { return -1; } LIB_EXPORT int jack_remove_properties(jack_client_t*, jack_uuid_t) { return -1; } LIB_EXPORT int jack_remove_all_properties(jack_client_t*) { return -1; } LIB_EXPORT int jack_set_property_change_callback(jack_client_t*, JackPropertyChangeCallback, void*) { return -1; } LIB_EXPORT jack_uuid_t jack_client_uuid_generate() { return 0; } LIB_EXPORT jack_uuid_t jack_port_uuid_generate(uint32_t) { return 0; } LIB_EXPORT uint32_t jack_uuid_to_index(jack_uuid_t) { return 0; } LIB_EXPORT int jack_uuid_compare(jack_uuid_t, jack_uuid_t) { return 0; } LIB_EXPORT void jack_uuid_copy(jack_uuid_t*, jack_uuid_t) { } LIB_EXPORT void jack_uuid_clear(jack_uuid_t*) { } LIB_EXPORT int jack_uuid_parse(const char*, jack_uuid_t*) { return 0; } LIB_EXPORT void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]) { } LIB_EXPORT int jack_uuid_empty(jack_uuid_t) { return 0; } 1.9.12~dfsg/common/JackRestartThreadedDriver.h0000644000000000000000000000241613214314510020036 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackRestartThreadedDriver__ #define __JackRestartThreadedDriver__ #include "JackThreadedDriver.h" namespace Jack { /*! \brief Restart a driver after an exception is thrown. */ class SERVER_EXPORT JackRestartThreadedDriver : public JackThreadedDriver { public: JackRestartThreadedDriver(JackDriver* driver) :JackThreadedDriver(driver) {} virtual ~JackRestartThreadedDriver() {} // JackRunnableInterface interface virtual bool Execute(); }; } // end of namespace #endif 1.9.12~dfsg/common/JackNetDriver.cpp0000644000000000000000000010426013214314510016032 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackCompilerDeps.h" #include "driver_interface.h" #include "JackNetDriver.h" #include "JackEngineControl.h" #include "JackLockedEngine.h" #include "JackWaitThreadedDriver.h" using namespace std; namespace Jack { JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports, char* net_name, uint transport_sync, int network_latency, int celt_encoding, int opus_encoding, bool auto_save) : JackWaiterDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port) { jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port); // Use the hostname if no name parameter was given if (strcmp(net_name, "") == 0) { GetHostName(net_name, JACK_CLIENT_NAME_SIZE); } fParams.fMtu = mtu; fWantedMIDICaptureChannels = midi_input_ports; fWantedMIDIPlaybackChannels = midi_output_ports; if (celt_encoding > 0) { fParams.fSampleEncoder = JackCeltEncoder; fParams.fKBps = celt_encoding; } else if (opus_encoding > 0) { fParams.fSampleEncoder = JackOpusEncoder; fParams.fKBps = opus_encoding; } else { fParams.fSampleEncoder = JackFloatEncoder; //fParams.fSampleEncoder = JackIntEncoder; } strcpy(fParams.fName, net_name); fSocket.GetName(fParams.fSlaveNetName); fParams.fTransportSync = transport_sync; fParams.fNetworkLatency = network_latency; fSendTransportData.fState = -1; fReturnTransportData.fState = -1; fLastTransportState = -1; fLastTimebaseMaster = -1; fMidiCapturePortList = NULL; fMidiPlaybackPortList = NULL; fWantedAudioCaptureChannels = -1; fWantedAudioPlaybackChannels = -1; fAutoSave = auto_save; #ifdef JACK_MONITOR fNetTimeMon = NULL; fRcvSyncUst = 0; #endif } JackNetDriver::~JackNetDriver() { delete[] fMidiCapturePortList; delete[] fMidiPlaybackPortList; #ifdef JACK_MONITOR delete fNetTimeMon; #endif } //open, close, attach and detach------------------------------------------------------ int JackNetDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { // Keep initial wanted values fWantedAudioCaptureChannels = inchannels; fWantedAudioPlaybackChannels = outchannels; return JackWaiterDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } int JackNetDriver::Close() { #ifdef JACK_MONITOR if (fNetTimeMon) { fNetTimeMon->Save(); } #endif FreeAll(); return JackWaiterDriver::Close(); } // Attach and Detach are defined as empty methods: port allocation is done when driver actually start (that is in Init) int JackNetDriver::Attach() { return 0; } int JackNetDriver::Detach() { return 0; } //init and restart-------------------------------------------------------------------- /* JackNetDriver is wrapped in a JackWaitThreadedDriver decorator that behaves as a "dummy driver, until Init method returns. */ bool JackNetDriver::Initialize() { jack_log("JackNetDriver::Initialize"); if (fAutoSave) { SaveConnections(0); } FreePorts(); // New loading, but existing socket, restart the driver if (fSocket.IsSocket()) { jack_info("Restarting driver..."); FreeAll(); } // Set the parameters to send fParams.fSendAudioChannels = fWantedAudioCaptureChannels; fParams.fReturnAudioChannels = fWantedAudioPlaybackChannels; fParams.fSendMidiChannels = fWantedMIDICaptureChannels; fParams.fReturnMidiChannels = fWantedMIDIPlaybackChannels; fParams.fSlaveSyncMode = fEngineControl->fSyncMode; // Display some additional infos jack_info("NetDriver started in %s mode %s Master's transport sync.", (fParams.fSlaveSyncMode) ? "sync" : "async", (fParams.fTransportSync) ? "with" : "without"); // Init network if (!JackNetSlaveInterface::Init()) { jack_error("Starting network fails..."); return false; } // Set global parameters if (!SetParams()) { jack_error("SetParams error..."); return false; } // If -1 at connection time for audio, in/out audio channels count is sent by the master fCaptureChannels = fParams.fSendAudioChannels; fPlaybackChannels = fParams.fReturnAudioChannels; // If -1 at connection time for MIDI, in/out MIDI channels count is sent by the master (in fParams struct) // Allocate midi ports lists delete[] fMidiCapturePortList; delete[] fMidiPlaybackPortList; if (fParams.fSendMidiChannels > 0) { fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; assert(fMidiCapturePortList); for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { fMidiCapturePortList[midi_port_index] = 0; } } if (fParams.fReturnMidiChannels > 0) { fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels]; assert(fMidiPlaybackPortList); for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { fMidiPlaybackPortList[midi_port_index] = 0; } } // Register jack ports if (AllocPorts() != 0) { jack_error("Can't allocate ports."); return false; } // Init done, display parameters SessionParamsDisplay(&fParams); // Monitor #ifdef JACK_MONITOR string plot_name; // NetTimeMon plot_name = string(fParams.fName); plot_name += string("_slave"); plot_name += (fEngineControl->fSyncMode) ? string("_sync") : string("_async"); plot_name += string("_latency"); fNetTimeMon = new JackGnuPlotMonitor(128, 5, plot_name); string net_time_mon_fields[] = { string("sync decoded"), string("end of read"), string("start of write"), string("sync send"), string("end of write") }; string net_time_mon_options[] = { string("set xlabel \"audio cycles\""), string("set ylabel \"% of audio cycle\"") }; fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 5); #endif // Driver parametering JackTimedDriver::SetBufferSize(fParams.fPeriodSize); JackTimedDriver::SetSampleRate(fParams.fSampleRate); JackDriver::NotifyBufferSize(fParams.fPeriodSize); JackDriver::NotifySampleRate(fParams.fSampleRate); // Transport engine parametering fEngineControl->fTransport.SetNetworkSync(fParams.fTransportSync); if (fAutoSave) { LoadConnections(0); } return true; } void JackNetDriver::FreeAll() { FreePorts(); delete[] fTxBuffer; delete[] fRxBuffer; delete fNetAudioCaptureBuffer; delete fNetAudioPlaybackBuffer; delete fNetMidiCaptureBuffer; delete fNetMidiPlaybackBuffer; delete[] fMidiCapturePortList; delete[] fMidiPlaybackPortList; fTxBuffer = NULL; fRxBuffer = NULL; fNetAudioCaptureBuffer = NULL; fNetAudioPlaybackBuffer = NULL; fNetMidiCaptureBuffer = NULL; fNetMidiPlaybackBuffer = NULL; fMidiCapturePortList = NULL; fMidiPlaybackPortList = NULL; #ifdef JACK_MONITOR delete fNetTimeMon; fNetTimeMon = NULL; #endif } void JackNetDriver::UpdateLatencies() { jack_latency_range_t input_range; jack_latency_range_t output_range; jack_latency_range_t monitor_range; for (int i = 0; i < fCaptureChannels; i++) { input_range.max = input_range.min = float(fParams.fNetworkLatency * fEngineControl->fBufferSize) / 2.f; fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); } for (int i = 0; i < fPlaybackChannels; i++) { output_range.max = output_range.min = float(fParams.fNetworkLatency * fEngineControl->fBufferSize) / 2.f; if (!fEngineControl->fSyncMode) { output_range.max = output_range.min += fEngineControl->fBufferSize; } fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); if (fWithMonitorPorts) { monitor_range.min = monitor_range.max = 0; fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range); } } } //jack ports and buffers-------------------------------------------------------------- int JackNetDriver::AllocPorts() { jack_log("JackNetDriver::AllocPorts fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); /* fNetAudioCaptureBuffer fNetAudioPlaybackBuffer fSendAudioChannels fReturnAudioChannels fCapturePortList fPlaybackPortList fCaptureChannels ==> SLAVE ==> fPlaybackChannels "capture_" "playback_" */ JackPort* port; jack_port_id_t port_index; char name[REAL_JACK_PORT_NAME_SIZE+1]; char alias[REAL_JACK_PORT_NAME_SIZE+1]; int audio_port_index; int midi_port_index; //audio for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) { snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1); snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, audio_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fCapturePortList[audio_port_index] = port_index; jack_log("JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency()); } for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1); snprintf(name, sizeof(name), "%s:playback_%d",fClientControl.fName, audio_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fPlaybackPortList[audio_port_index] = port_index; jack_log("JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency()); } //midi for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1); snprintf(name, sizeof (name), "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); fMidiCapturePortList[midi_port_index] = port_index; jack_log("JackNetDriver::AllocPorts() fMidiCapturePortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency()); } for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1); snprintf(name, sizeof(name), "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); fMidiPlaybackPortList[midi_port_index] = port_index; jack_log("JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency()); } UpdateLatencies(); return 0; } int JackNetDriver::FreePorts() { jack_log("JackNetDriver::FreePorts"); for (int audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) { if (fCapturePortList[audio_port_index] > 0) { fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[audio_port_index]); fCapturePortList[audio_port_index] = 0; } } for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { if (fPlaybackPortList[audio_port_index] > 0) { fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[audio_port_index]); fPlaybackPortList[audio_port_index] = 0; } } for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { if (fMidiCapturePortList && fMidiCapturePortList[midi_port_index] > 0) { fGraphManager->ReleasePort(fClientControl.fRefNum, fMidiCapturePortList[midi_port_index]); fMidiCapturePortList[midi_port_index] = 0; } } for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { if (fMidiPlaybackPortList && fMidiPlaybackPortList[midi_port_index] > 0) { fEngine->PortUnRegister(fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index]); fMidiPlaybackPortList[midi_port_index] = 0; } } return 0; } void JackNetDriver::SaveConnections(int alias) { JackDriver::SaveConnections(alias); const char** connections; if (fMidiCapturePortList) { for (int i = 0; i < fParams.fSendMidiChannels; ++i) { if (fMidiCapturePortList[i] && (connections = fGraphManager->GetConnections(fMidiCapturePortList[i])) != 0) { for (int j = 0; connections[j]; j++) { JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j])); fConnections.push_back(make_pair(port_id->GetType(), make_pair(fGraphManager->GetPort(fMidiCapturePortList[i])->GetName(), connections[j]))); jack_info("Save connection: %s %s", fGraphManager->GetPort(fMidiCapturePortList[i])->GetName(), connections[j]); } free(connections); } } } if (fMidiPlaybackPortList) { for (int i = 0; i < fParams.fReturnMidiChannels; ++i) { if (fMidiPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fMidiPlaybackPortList[i])) != 0) { for (int j = 0; connections[j]; j++) { JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j])); fConnections.push_back(make_pair(port_id->GetType(), make_pair(connections[j], fGraphManager->GetPort(fMidiPlaybackPortList[i])->GetName()))); jack_info("Save connection: %s %s", connections[j], fGraphManager->GetPort(fMidiPlaybackPortList[i])->GetName()); } free(connections); } } } } JackMidiBuffer* JackNetDriver::GetMidiInputBuffer(int port_index) { return static_cast(fGraphManager->GetBuffer(fMidiCapturePortList[port_index], fEngineControl->fBufferSize)); } JackMidiBuffer* JackNetDriver::GetMidiOutputBuffer(int port_index) { return static_cast(fGraphManager->GetBuffer(fMidiPlaybackPortList[port_index], fEngineControl->fBufferSize)); } //transport--------------------------------------------------------------------------- void JackNetDriver::DecodeTransportData() { //is there a new timebase master on the net master ? // - release timebase master only if it's a non-conditional request // - no change or no request : don't do anything // - conditional request : don't change anything too, the master will know if this slave is actually the timebase master int refnum; bool conditional; if (fSendTransportData.fTimebaseMaster == TIMEBASEMASTER) { fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional); if (refnum != -1) { fEngineControl->fTransport.ResetTimebase(refnum); } jack_info("The NetMaster is now the new timebase master."); } //is there a transport state change to handle ? if (fSendTransportData.fNewState &&(fSendTransportData.fState != fEngineControl->fTransport.GetState())) { switch (fSendTransportData.fState) { case JackTransportStopped : fEngineControl->fTransport.SetCommand(TransportCommandStop); jack_info("Master stops transport."); break; case JackTransportStarting : fEngineControl->fTransport.RequestNewPos(&fSendTransportData.fPosition); fEngineControl->fTransport.SetCommand(TransportCommandStart); jack_info("Master starts transport frame = %d", fSendTransportData.fPosition.frame); break; case JackTransportRolling : //fEngineControl->fTransport.SetCommand(TransportCommandStart); fEngineControl->fTransport.SetState(JackTransportRolling); jack_info("Master is rolling."); break; } } } void JackNetDriver::EncodeTransportData() { // is there a timebase master change ? int refnum; bool conditional; fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional); if (refnum != fLastTimebaseMaster) { // timebase master has released its function if (refnum == -1) { fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER; jack_info("Sending a timebase master release request."); } else { // there is a new timebase master fReturnTransportData.fTimebaseMaster = (conditional) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER; jack_info("Sending a %s timebase master request.", (conditional) ? "conditional" : "non-conditional"); } fLastTimebaseMaster = refnum; } else { fReturnTransportData.fTimebaseMaster = NO_CHANGE; } // update transport state and position fReturnTransportData.fState = fEngineControl->fTransport.Query(&fReturnTransportData.fPosition); // is it a new state (that the master need to know...) ? fReturnTransportData.fNewState = ((fReturnTransportData.fState == JackTransportNetStarting) && (fReturnTransportData.fState != fLastTransportState) && (fReturnTransportData.fState != fSendTransportData.fState)); if (fReturnTransportData.fNewState) { jack_info("Sending '%s'.", GetTransportState(fReturnTransportData.fState)); } fLastTransportState = fReturnTransportData.fState; } //driver processes-------------------------------------------------------------------- int JackNetDriver::Read() { // buffers for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { fNetMidiCaptureBuffer->SetBuffer(midi_port_index, GetMidiInputBuffer(midi_port_index)); } for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { #ifdef OPTIMIZED_PROTOCOL if (fGraphManager->GetConnectionsNum(fCapturePortList[audio_port_index]) > 0) { fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index)); } else { fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL); } #else fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index)); #endif } #ifdef JACK_MONITOR fNetTimeMon->New(); #endif switch (SyncRecv()) { case SOCKET_ERROR: return SOCKET_ERROR; case SYNC_PACKET_ERROR: // since sync packet is incorrect, don't decode it and continue with data break; default: // decode sync int unused_frames; DecodeSyncPacket(unused_frames); break; } #ifdef JACK_MONITOR // For timing fRcvSyncUst = GetMicroSeconds(); #endif #ifdef JACK_MONITOR fNetTimeMon->Add(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); #endif // audio, midi or sync if driver is late switch (DataRecv()) { case SOCKET_ERROR: return SOCKET_ERROR; case DATA_PACKET_ERROR: jack_time_t cur_time = GetMicroSeconds(); NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... break; } // take the time at the beginning of the cycle JackDriver::CycleTakeBeginTime(); #ifdef JACK_MONITOR fNetTimeMon->Add(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); #endif return 0; } int JackNetDriver::Write() { // buffers for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, GetMidiOutputBuffer(midi_port_index)); } for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { #ifdef OPTIMIZED_PROTOCOL // Port is connected on other side... if (fNetAudioPlaybackBuffer->GetConnected(audio_port_index) && (fGraphManager->GetConnectionsNum(fPlaybackPortList[audio_port_index]) > 0)) { fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index)); } else { fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL); } #else fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index)); #endif } #ifdef JACK_MONITOR fNetTimeMon->AddLast(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); #endif EncodeSyncPacket(); // send sync if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; } #ifdef JACK_MONITOR fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f); #endif // send data if (DataSend() == SOCKET_ERROR) { return SOCKET_ERROR; } #ifdef JACK_MONITOR fNetTimeMon->AddLast(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f); #endif return 0; } //driver loader----------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("net", JackDriverMaster, "netjack slave backend component", &filler); strcpy(value.str, DEFAULT_MULTICAST_IP); jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address, or explicit IP of the master", NULL); value.i = DEFAULT_PORT; jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL); value.i = DEFAULT_MTU; jack_driver_descriptor_add_parameter(desc, &filler, "mtu", 'M', JackDriverParamInt, &value, NULL, "MTU to the master", NULL); value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "input-ports", 'C', JackDriverParamInt, &value, NULL, "Number of audio input ports", "Number of audio input ports. If -1, audio physical input from the master"); jack_driver_descriptor_add_parameter(desc, &filler, "output-ports", 'P', JackDriverParamInt, &value, NULL, "Number of audio output ports", "Number of audio output ports. If -1, audio physical output from the master"); value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "midi-in-ports", 'i', JackDriverParamInt, &value, NULL, "Number of midi input ports", "Number of MIDI input ports. If -1, MIDI physical input from the master"); jack_driver_descriptor_add_parameter(desc, &filler, "midi-out-ports", 'o', JackDriverParamInt, &value, NULL, "Number of midi output ports", "Number of MIDI output ports. If -1, MIDI physical output from the master"); #if HAVE_CELT value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamInt, &value, NULL, "Set CELT encoding and number of kBits per channel", NULL); #endif #if HAVE_OPUS value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'O', JackDriverParamInt, &value, NULL, "Set Opus encoding and number of kBits per channel", NULL); #endif strcpy(value.str, "'hostname'"); jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "auto-save", 's', JackDriverParamBool, &value, NULL, "Save/restore connection state when restarting", NULL); /* Deactivated for now.. value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL); */ value.ui = 5U; jack_driver_descriptor_add_parameter(desc, &filler, "latency", 'l', JackDriverParamUInt, &value, NULL, "Network latency", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { char multicast_ip[32]; char net_name[JACK_CLIENT_NAME_SIZE+1] = {0}; int udp_port; int mtu = DEFAULT_MTU; // Desactivated for now... uint transport_sync = 0; jack_nframes_t period_size = 1024; // to be used while waiting for master period_size jack_nframes_t sample_rate = 48000; // to be used while waiting for master sample_rate int audio_capture_ports = -1; int audio_playback_ports = -1; int midi_input_ports = -1; int midi_output_ports = -1; int celt_encoding = -1; int opus_encoding = -1; bool monitor = false; int network_latency = 5; const JSList* node; const jack_driver_param_t* param; bool auto_save = false; // Possibly use env variable for UDP port const char* default_udp_port = getenv("JACK_NETJACK_PORT"); udp_port = (default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT; // Possibly use env variable for multicast IP const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST"); strcpy(multicast_ip, (default_multicast_ip) ? default_multicast_ip : DEFAULT_MULTICAST_IP); for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'a' : assert(strlen(param->value.str) < 32); strcpy(multicast_ip, param->value.str); break; case 'p': udp_port = param->value.ui; break; case 'M': mtu = param->value.i; break; case 'C': audio_capture_ports = param->value.i; break; case 'P': audio_playback_ports = param->value.i; break; case 'i': midi_input_ports = param->value.i; break; case 'o': midi_output_ports = param->value.i; break; #if HAVE_CELT case 'c': celt_encoding = param->value.i; break; #endif #if HAVE_OPUS case 'O': opus_encoding = param->value.i; break; #endif case 'n' : strncpy(net_name, param->value.str, JACK_CLIENT_NAME_SIZE); break; case 's': auto_save = true; break; /* Deactivated for now.. case 't' : transport_sync = param->value.ui; break; */ case 'l' : network_latency = param->value.ui; if (network_latency > NETWORK_MAX_LATENCY) { printf("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY); return NULL; } break; } } try { Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver( new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu, midi_input_ports, midi_output_ports, net_name, transport_sync, network_latency, celt_encoding, opus_encoding, auto_save)); if (driver->Open(period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, monitor, "from_master_", "to_master_", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } catch (...) { return NULL; } } #ifdef __cplusplus } #endif } 1.9.12~dfsg/common/JackLoopbackDriver.h0000644000000000000000000000261413214314510016503 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackLoopbackDriver__ #define __JackLoopbackDriver__ #include "JackAudioDriver.h" namespace Jack { /*! \brief The loopback driver : to be used to "pipeline" applications connected in sequence. */ class JackLoopbackDriver : public JackAudioDriver { private: virtual int ProcessReadSync(); virtual int ProcessWriteSync(); virtual int ProcessReadAsync(); virtual int ProcessWriteAsync(); public: JackLoopbackDriver(JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver("loopback", "loopback", engine, table) {} virtual ~JackLoopbackDriver() {} }; } // end of namespace #endif 1.9.12~dfsg/common/JackProxyDriver.cpp0000644000000000000000000005332013214314510016425 0ustar rootroot/* Copyright (C) 2014 Cédric Schieli This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "JackCompilerDeps.h" #include "driver_interface.h" #include "JackEngineControl.h" #include "JackLockedEngine.h" #include "JackWaitCallbackDriver.h" #include "JackProxyDriver.h" using namespace std; namespace Jack { JackProxyDriver::JackProxyDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, const char* upstream, const char* promiscuous, char* client_name, bool auto_connect, bool auto_save) : JackRestarterDriver(name, alias, engine, table) { jack_log("JackProxyDriver::JackProxyDriver upstream %s", upstream); assert(strlen(upstream) < JACK_CLIENT_NAME_SIZE); strcpy(fUpstream, upstream); assert(strlen(client_name) < JACK_CLIENT_NAME_SIZE); strcpy(fClientName, client_name); if (promiscuous) { fPromiscuous = strdup(promiscuous); } fAutoConnect = auto_connect; fAutoSave = auto_save; } JackProxyDriver::~JackProxyDriver() { if (fHandle) { UnloadJackModule(fHandle); } } int JackProxyDriver::LoadClientLib() { // Already loaded if (fHandle) { return 0; } fHandle = LoadJackModule(JACK_PROXY_CLIENT_LIB); if (!fHandle) { return -1; } LoadSymbols(); return 0; } //open, close, attach and detach------------------------------------------------------ int JackProxyDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { fDetectPlaybackChannels = (outchannels == -1); fDetectCaptureChannels = (inchannels == -1); if (LoadClientLib() != 0) { jack_error("Cannot dynamically load client library !"); return -1; } return JackWaiterDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } int JackProxyDriver::Close() { FreePorts(); return JackWaiterDriver::Close(); } // Attach and Detach are defined as empty methods: port allocation is done when driver actually start (that is in Init) int JackProxyDriver::Attach() { return 0; } int JackProxyDriver::Detach() { return 0; } //init and restart-------------------------------------------------------------------- /* JackProxyDriver is wrapped in a JackWaitCallbackDriver decorator that behaves as a "dummy driver, until Initialize method returns. */ bool JackProxyDriver::Initialize() { jack_log("JackProxyDriver::Initialize"); // save existing local connections if needed if (fAutoSave) { SaveConnections(0); } // new loading, but existing client, restart the driver if (fClient) { jack_info("JackProxyDriver restarting..."); jack_client_close(fClient); } FreePorts(); // display some additional infos jack_info("JackProxyDriver started in %s mode.", (fEngineControl->fSyncMode) ? "sync" : "async"); do { jack_status_t status; char *old = NULL; if (fPromiscuous) { // as we are fiddling with the environment variable content, save it const char* tmp = getenv("JACK_PROMISCUOUS_SERVER"); if (tmp) { old = strdup(tmp); } // temporary enable promiscuous mode if (setenv("JACK_PROMISCUOUS_SERVER", fPromiscuous, 1) < 0) { free(old); jack_error("Error allocating memory."); return false; } } jack_info("JackProxyDriver connecting to %s", fUpstream); fClient = jack_client_open(fClientName, static_cast(JackNoStartServer|JackServerName), &status, fUpstream); if (fPromiscuous) { // restore previous environment variable content if (old) { if (setenv("JACK_PROMISCUOUS_SERVER", old, 1) < 0) { free(old); jack_error("Error allocating memory."); return false; } free(old); } else { unsetenv("JACK_PROMISCUOUS_SERVER"); } } // the connection failed, try again later if (!fClient) { JackSleep(1000000); } } while (!fClient); jack_info("JackProxyDriver connected to %s", fUpstream); // we are connected, let's register some callbacks jack_on_shutdown(fClient, shutdown_callback, this); if (jack_set_process_callback(fClient, process_callback, this) != 0) { jack_error("Cannot set process callback."); return false; } if (jack_set_buffer_size_callback(fClient, bufsize_callback, this) != 0) { jack_error("Cannot set buffer size callback."); return false; } if (jack_set_sample_rate_callback(fClient, srate_callback, this) != 0) { jack_error("Cannot set sample rate callback."); return false; } if (jack_set_port_connect_callback(fClient, connect_callback, this) != 0) { jack_error("Cannot set port connect callback."); return false; } // detect upstream physical playback ports if needed if (fDetectPlaybackChannels) { fPlaybackChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput); } // detect upstream physical capture ports if needed if (fDetectCaptureChannels) { fCaptureChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput); } if (AllocPorts() != 0) { jack_error("Can't allocate ports."); return false; } bufsize_callback(jack_get_buffer_size(fClient)); srate_callback(jack_get_sample_rate(fClient)); // restore local connections if needed if (fAutoSave) { LoadConnections(0); } // everything is ready, start upstream processing if (jack_activate(fClient) != 0) { jack_error("Cannot activate jack client."); return false; } // connect upstream ports if needed if (fAutoConnect) { ConnectPorts(); } return true; } int JackProxyDriver::Stop() { if (fClient && (jack_deactivate(fClient) != 0)) { jack_error("Cannot deactivate jack client."); return -1; } return 0; } //client callbacks--------------------------------------------------------------------------- int JackProxyDriver::process_callback(jack_nframes_t nframes, void* arg) { assert(static_cast(arg)); return static_cast(arg)->Process(); } int JackProxyDriver::bufsize_callback(jack_nframes_t nframes, void* arg) { assert(static_cast(arg)); return static_cast(arg)->bufsize_callback(nframes); } int JackProxyDriver::bufsize_callback(jack_nframes_t nframes) { if (JackTimedDriver::SetBufferSize(nframes) == 0) { return -1; } JackDriver::NotifyBufferSize(nframes); return 0; } int JackProxyDriver::srate_callback(jack_nframes_t nframes, void* arg) { assert(static_cast(arg)); return static_cast(arg)->srate_callback(nframes); } int JackProxyDriver::srate_callback(jack_nframes_t nframes) { if (JackTimedDriver::SetSampleRate(nframes) == 0) { return -1; } JackDriver::NotifySampleRate(nframes); return 0; } void JackProxyDriver::connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg) { assert(static_cast(arg)); static_cast(arg)->connect_callback(a, b, connect); } void JackProxyDriver::connect_callback(jack_port_id_t a, jack_port_id_t b, int connect) { jack_port_t* port; int i; // skip port if not our own port = jack_port_by_id(fClient, a); if (!jack_port_is_mine(fClient, port)) { port = jack_port_by_id(fClient, b); if (!jack_port_is_mine(fClient, port)) { return; } } for (i = 0; i < fCaptureChannels; i++) { if (fUpstreamPlaybackPorts[i] == port) { fUpstreamPlaybackPortConnected[i] = connect; } } for (i = 0; i < fPlaybackChannels; i++) { if (fUpstreamCapturePorts[i] == port) { fUpstreamCapturePortConnected[i] = connect; } } } void JackProxyDriver::shutdown_callback(void* arg) { assert(static_cast(arg)); static_cast(arg)->RestartWait(); } //jack ports and buffers-------------------------------------------------------------- int JackProxyDriver::CountIO(const char* type, int flags) { int count = 0; const char** ports = jack_get_ports(fClient, NULL, type, flags); if (ports != NULL) { while (ports[count]) { count++; } jack_free(ports); } return count; } int JackProxyDriver::AllocPorts() { jack_log("JackProxyDriver::AllocPorts fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); char proxy[REAL_JACK_PORT_NAME_SIZE]; int i; fUpstreamPlaybackPorts = new jack_port_t* [fCaptureChannels]; fUpstreamPlaybackPortConnected = new int [fCaptureChannels]; for (i = 0; i < fCaptureChannels; i++) { snprintf(proxy, sizeof(proxy), "%s:to_client_%d", fClientName, i + 1); fUpstreamPlaybackPorts[i] = jack_port_register(fClient, proxy, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0); if (fUpstreamPlaybackPorts[i] == NULL) { jack_error("driver: cannot register upstream port %s", proxy); return -1; } fUpstreamPlaybackPortConnected[i] = 0; } fUpstreamCapturePorts = new jack_port_t* [fPlaybackChannels]; fUpstreamCapturePortConnected = new int [fPlaybackChannels]; for (i = 0; i < fPlaybackChannels; i++) { snprintf(proxy, sizeof(proxy), "%s:from_client_%d", fClientName, i + 1); fUpstreamCapturePorts[i] = jack_port_register(fClient, proxy, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0); if (fUpstreamCapturePorts[i] == NULL) { jack_error("driver: cannot register upstream port %s", proxy); return -1; } fUpstreamCapturePortConnected[i] = 0; } // local ports are registered here return JackAudioDriver::Attach(); } int JackProxyDriver::FreePorts() { jack_log("JackProxyDriver::FreePorts"); int i; for (i = 0; i < fCaptureChannels; i++) { if (fCapturePortList[i] > 0) { fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[i]); fCapturePortList[i] = 0; } if (fUpstreamPlaybackPorts && fUpstreamPlaybackPorts[i]) { fUpstreamPlaybackPorts[i] = NULL; } } for (i = 0; i < fPlaybackChannels; i++) { if (fPlaybackPortList[i] > 0) { fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[i]); fPlaybackPortList[i] = 0; } if (fUpstreamCapturePorts && fUpstreamCapturePorts[i]) { fUpstreamCapturePorts[i] = NULL; } } delete[] fUpstreamPlaybackPorts; delete[] fUpstreamPlaybackPortConnected; delete[] fUpstreamCapturePorts; delete[] fUpstreamCapturePortConnected; fUpstreamPlaybackPorts = NULL; fUpstreamPlaybackPortConnected = NULL; fUpstreamCapturePorts = NULL; fUpstreamCapturePortConnected = NULL; return 0; } void JackProxyDriver::ConnectPorts() { jack_log("JackProxyDriver::ConnectPorts"); const char** ports = jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput); if (ports != NULL) { for (int i = 0; i < fCaptureChannels && ports[i]; i++) { jack_connect(fClient, ports[i], jack_port_name(fUpstreamPlaybackPorts[i])); } jack_free(ports); } ports = jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput); if (ports != NULL) { for (int i = 0; i < fPlaybackChannels && ports[i]; i++) { jack_connect(fClient, jack_port_name(fUpstreamCapturePorts[i]), ports[i]); } jack_free(ports); } } //driver processes-------------------------------------------------------------------- int JackProxyDriver::Read() { // take the time at the beginning of the cycle JackDriver::CycleTakeBeginTime(); int i; void *from, *to; size_t buflen = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; for (i = 0; i < fCaptureChannels; i++) { if (fUpstreamPlaybackPortConnected[i]) { from = jack_port_get_buffer(fUpstreamPlaybackPorts[i], fEngineControl->fBufferSize); to = GetInputBuffer(i); memcpy(to, from, buflen); } } return 0; } int JackProxyDriver::Write() { int i; void *from, *to; size_t buflen = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; for (i = 0; i < fPlaybackChannels; i++) { if (fUpstreamCapturePortConnected[i]) { to = jack_port_get_buffer(fUpstreamCapturePorts[i], fEngineControl->fBufferSize); from = GetOutputBuffer(i); memcpy(to, from, buflen); } } return 0; } //driver loader----------------------------------------------------------------------- #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("proxy", JackDriverMaster, "proxy backend", &filler); strcpy(value.str, DEFAULT_UPSTREAM); jack_driver_descriptor_add_parameter(desc, &filler, "upstream", 'u', JackDriverParamString, &value, NULL, "Name of the upstream jack server", NULL); strcpy(value.str, ""); jack_driver_descriptor_add_parameter(desc, &filler, "promiscuous", 'p', JackDriverParamString, &value, NULL, "Promiscuous group", NULL); value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "input-ports", 'C', JackDriverParamInt, &value, NULL, "Number of audio input ports", "Number of audio input ports. If -1, audio physical input from the master"); jack_driver_descriptor_add_parameter(desc, &filler, "output-ports", 'P', JackDriverParamInt, &value, NULL, "Number of audio output ports", "Number of audio output ports. If -1, audio physical output from the master"); strcpy(value.str, "proxy"); jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "use-username", 'U', JackDriverParamBool, &value, NULL, "Use current username as client name", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "auto-connect", 'c', JackDriverParamBool, &value, NULL, "Auto connect proxy to upstream system ports", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "auto-save", 's', JackDriverParamBool, &value, NULL, "Save/restore connection state when restarting", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { char upstream[JACK_CLIENT_NAME_SIZE + 1]; char promiscuous[JACK_CLIENT_NAME_SIZE + 1] = {0}; char client_name[JACK_CLIENT_NAME_SIZE + 1]; jack_nframes_t period_size = 1024; // to be used while waiting for master period_size jack_nframes_t sample_rate = 48000; // to be used while waiting for master sample_rate int capture_ports = -1; int playback_ports = -1; const JSList* node; const jack_driver_param_t* param; bool auto_connect = false; bool auto_save = false; bool use_promiscuous = false; // Possibly use env variable for upstream name const char* default_upstream = getenv("JACK_PROXY_UPSTREAM"); strcpy(upstream, (default_upstream) ? default_upstream : DEFAULT_UPSTREAM); // Possibly use env variable for upstream promiscuous const char* default_promiscuous = getenv("JACK_PROXY_PROMISCUOUS"); strcpy(promiscuous, (default_promiscuous) ? default_promiscuous : ""); // Possibly use env variable for client name const char* default_client_name = getenv("JACK_PROXY_CLIENT_NAME"); strcpy(client_name, (default_client_name) ? default_client_name : DEFAULT_CLIENT_NAME); #ifdef WIN32 const char* username = getenv("USERNAME"); #else const char* username = getenv("LOGNAME"); #endif for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'u' : assert(strlen(param->value.str) < JACK_CLIENT_NAME_SIZE); strcpy(upstream, param->value.str); break; case 'p': assert(strlen(param->value.str) < JACK_CLIENT_NAME_SIZE); use_promiscuous = true; strcpy(promiscuous, param->value.str); break; case 'C': capture_ports = param->value.i; break; case 'P': playback_ports = param->value.i; break; case 'n' : assert(strlen(param->value.str) < JACK_CLIENT_NAME_SIZE); strncpy(client_name, param->value.str, JACK_CLIENT_NAME_SIZE); break; case 'U' : if (username && *username) { assert(strlen(username) < JACK_CLIENT_NAME_SIZE); strncpy(client_name, username, JACK_CLIENT_NAME_SIZE); } case 'c': auto_connect = true; break; case 's': auto_save = true; break; } } try { Jack::JackDriverClientInterface* driver = new Jack::JackWaitCallbackDriver( new Jack::JackProxyDriver("system", "proxy_pcm", engine, table, upstream, use_promiscuous ? promiscuous : NULL, client_name, auto_connect, auto_save)); if (driver->Open(period_size, sample_rate, 1, 1, capture_ports, playback_ports, false, "capture_", "playback_", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } catch (...) { return NULL; } } #ifdef __cplusplus } #endif } 1.9.12~dfsg/common/wscript0000644000000000000000000003572713214314510014264 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 import re import os def configure(conf): conf.env['BUILD_NETLIB'] = conf.env['SAMPLERATE'] conf.env['BUILD_ADAPTER'] = conf.env['SAMPLERATE'] if conf.env['IS_WINDOWS']: try: conf.check(function_name='regcomp', header_name='regex.h', lib='regex', uselib_store='REGEX', define_name='HAVE_REGEX_H') except: conf.check(function_name='regcomp', header_name='regex.h', lib='tre', uselib_store='REGEX', define_name='HAVE_REGEX_H') conf.check(function_name='htons', header_name='winsock2.h', lib='ws2_32', uselib_store='WS2_32', define_name='HAVE_WINSOCK2_H') conf.check(function_name='timeGetDevCaps', header_name=['windows.h', 'mmsystem.h'], lib='winmm', uselib_store='WINMM', define_name='HAVE_MMSYSTEM_H') conf.check(function_name='EnumProcesses', header_name=['windows.h', 'psapi.h'], lib='psapi', uselib_store='PSAPI', define_name='HAVE_PSAPI_H') def create_jack_process_obj(bld, target, sources, uselib = None, framework = None): process = bld(features = ['cxx', 'cxxshlib']) if not bld.env['IS_WINDOWS']: process.env['cxxshlib_PATTERN'] = '%s.so' process.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] if bld.env['IS_MACOSX']: if framework: process.framework = framework env_includes = ['../macosx', '../posix', '../macosx/coreaudio'] if bld.env['IS_LINUX']: env_includes = ['../linux', '../posix', '../linux/alsa'] if bld.env['IS_SUN']: env_includes = ['../solaris', '../posix', '../solaris/oss'] if bld.env['IS_WINDOWS']: env_includes = ['../windows', '../windows/portaudio'] process.includes = ['.'] + env_includes + ['jack', '..'] process.name = target process.target = target process.source = sources if bld.env['IS_LINUX'] or bld.env['IS_MACOSX']: process.env.append_value('CPPFLAGS', '-fvisibility=hidden') process.install_path = '${ADDON_DIR}/' process.use = [uselib.name] return process def build(bld): common_libsources = [ 'JackActivationCount.cpp', 'JackAPI.cpp', 'JackClient.cpp', 'JackConnectionManager.cpp', 'ringbuffer.c', 'JackError.cpp', 'JackException.cpp', 'JackFrameTimer.cpp', 'JackGraphManager.cpp', 'JackPort.cpp', 'JackPortType.cpp', 'JackAudioPort.cpp', 'JackMidiPort.cpp', 'JackMidiAPI.cpp', 'JackEngineControl.cpp', 'JackShmMem.cpp', 'JackGenericClientChannel.cpp', 'shm.c', 'JackGlobals.cpp', 'JackTransportEngine.cpp', 'JackTools.cpp', 'JackMessageBuffer.cpp', 'JackEngineProfiling.cpp', ] includes = ['.', './jack'] if not bld.variant: includes.append('..') else: includes.append('../..') uselib = ['PTHREAD', 'CELT', 'OPUS'] if bld.env['IS_LINUX']: common_libsources += [ 'JackDebugClient.cpp', 'timestamps.c', 'promiscuous.c', '../posix/JackPosixThread.cpp', '../posix/JackPosixProcessSync.cpp', '../posix/JackPosixMutex.cpp', '../posix/JackSocket.cpp', '../linux/JackLinuxFutex.cpp', '../linux/JackLinuxTime.c', ] includes = ['../linux', '../posix'] + includes uselib.append('RT') uselib.append('DL') if bld.env['IS_SUN']: common_libsources += [ 'JackDebugClient.cpp', 'timestamps.c', 'promiscuous.c', '../posix/JackPosixThread.cpp', '../posix/JackFifo.cpp', '../posix/JackPosixProcessSync.cpp', '../posix/JackPosixMutex.cpp', '../posix/JackSocket.cpp', '../solaris/JackSolarisTime.c', ] includes = ['../solaris', '../posix'] + includes uselib.append('RT') if bld.env['IS_MACOSX']: common_libsources += [ 'JackDebugClient.cpp', 'timestamps.c', 'promiscuous.c', '../posix/JackPosixProcessSync.cpp', '../posix/JackPosixThread.cpp', '../posix/JackPosixMutex.cpp', '../macosx/JackMachThread.mm', #'../macosx/JackMachSemaphore.mm', '../posix/JackPosixSemaphore.cpp', '../posix/JackSocket.cpp', '../macosx/JackMachTime.c', ] includes = ['../macosx', '../macosx/RPC', '../posix'] + includes if bld.env['IS_WINDOWS']: common_libsources += [ '../windows/JackWinMutex.cpp', '../windows/JackWinProcessSync.cpp', '../windows/JackWinSemaphore.cpp', '../windows/JackWinThread.cpp', '../windows/JackWinTime.c', ] includes = ['../windows' ] + includes uselib.append('REGEX') uselib.append('WS2_32') uselib.append('PSAPI') uselib.append('WINMM') clientlib = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) if bld.env['IS_MACOSX']: clientlib.framework = ['CoreAudio', 'Accelerate'] clientlib.defines = 'HAVE_CONFIG_H' clientlib.use = uselib if bld.env['IS_WINDOWS']: clientlib.env['cxxshlib_PATTERN'] = 'lib%s.dll' clientlib.install_path = '${BINDIR}' else: clientlib.install_path = '${LIBDIR}' if bld.env['AUTOSTART_METHOD'] == 'dbus': clientlib.use.append('DBUS-1') clientlib.includes = includes clientlib.name = 'clientlib' clientlib.target = 'jack' clientlib.source = [] + common_libsources clientlib.source += [ 'JackLibClient.cpp', 'JackLibAPI.cpp', ] if bld.env['IS_LINUX']: clientlib.source += [ '../posix/JackSocketClientChannel.cpp', '../posix/JackPosixServerLaunch.cpp', ] if bld.env['IS_SUN']: clientlib.source += [ '../posix/JackSocketClientChannel.cpp', '../posix/JackPosixServerLaunch.cpp', ] if bld.env['IS_MACOSX']: clientlib.source += [ '../posix/JackSocketClientChannel.cpp', '../posix/JackPosixServerLaunch.cpp', ] if bld.env['IS_WINDOWS']: clientlib.source += [ '../windows/JackWinNamedPipe.cpp', '../windows/JackWinNamedPipeClientChannel.cpp', '../windows/JackWinServerLaunch.cpp', '../windows/JackMMCSS.cpp', ] clientlib.vnum = bld.env['JACK_API_VERSION'] if bld.env['IS_LINUX']: clientlib.env.append_value('CPPFLAGS', '-fvisibility=hidden') if bld.env['IS_MACOSX']: clientlib.env.append_value('CPPFLAGS', '-fvisibility=hidden') clientlib.env.append_value('LINKFLAGS', '-single_module') if bld.env['IS_SUN']: clientlib.env.append_value('LINKFLAGS', '-lnsl -lsocket') if bld.variant: # if there is variant defined, we expect it to be the 32bit client lib one # we don't want to build other stuff in this variant return serverlib = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) if bld.env['IS_MACOSX']: serverlib.framework = ['CoreAudio', 'CoreFoundation', 'Accelerate'] serverlib.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] serverlib.includes = includes serverlib.name = 'serverlib' serverlib.target = 'jackserver' serverlib.use = uselib if bld.env['IS_WINDOWS']: serverlib.env['cxxshlib_PATTERN'] = 'lib%s.dll' serverlib.install_path = '${BINDIR}' else: serverlib.install_path = '${LIBDIR}' serverlib.source = [] + common_libsources serverlib.source += [ 'JackAudioDriver.cpp', 'JackTimedDriver.cpp', 'JackMidiDriver.cpp', 'JackDriver.cpp', 'JackEngine.cpp', 'JackExternalClient.cpp', 'JackFreewheelDriver.cpp', 'JackInternalClient.cpp', 'JackInternalSessionLoader.cpp', 'JackServer.cpp', 'JackThreadedDriver.cpp', 'JackRestartThreadedDriver.cpp', 'JackWaitThreadedDriver.cpp', 'JackWaitCallbackDriver.cpp', 'JackServerAPI.cpp', 'JackDriverLoader.cpp', 'JackServerGlobals.cpp', 'JackControlAPI.cpp', 'JackNetTool.cpp', 'JackNetInterface.cpp', 'JackArgParser.cpp', 'JackRequestDecoder.cpp', 'JackMidiAsyncQueue.cpp', 'JackMidiAsyncWaitQueue.cpp', 'JackMidiBufferReadQueue.cpp', 'JackMidiBufferWriteQueue.cpp', 'JackMidiRawInputWriteQueue.cpp', 'JackMidiRawOutputWriteQueue.cpp', 'JackMidiReadQueue.cpp', 'JackMidiReceiveQueue.cpp', 'JackMidiSendQueue.cpp', 'JackMidiUtil.cpp', 'JackMidiWriteQueue.cpp', ] if bld.env['IS_LINUX']: serverlib.source += [ '../posix/JackSocketServerChannel.cpp', '../posix/JackSocketNotifyChannel.cpp', '../posix/JackSocketServerNotifyChannel.cpp', '../posix/JackNetUnixSocket.cpp', ] if bld.env['IS_SUN']: serverlib.source += [ '../posix/JackSocketServerChannel.cpp', '../posix/JackSocketNotifyChannel.cpp', '../posix/JackSocketServerNotifyChannel.cpp', '../posix/JackNetUnixSocket.cpp', ] if bld.env['IS_MACOSX']: serverlib.source += [ '../posix/JackSocketServerChannel.cpp', '../posix/JackSocketNotifyChannel.cpp', '../posix/JackSocketServerNotifyChannel.cpp', '../posix/JackNetUnixSocket.cpp', ] if bld.env['IS_WINDOWS']: serverlib.source += [ '../windows/JackMMCSS.cpp', '../windows/JackWinNamedPipe.cpp', '../windows/JackWinNamedPipeServerChannel.cpp', '../windows/JackWinNamedPipeServerNotifyChannel.cpp', '../windows/JackWinNamedPipeNotifyChannel.cpp', '../windows/JackNetWinSocket.cpp', ] serverlib.vnum = bld.env['JACK_API_VERSION'] if bld.env['IS_LINUX']: serverlib.env.append_value('CPPFLAGS', '-fvisibility=hidden') if bld.env['IS_MACOSX']: serverlib.env.append_value('CPPFLAGS', '-fvisibility=hidden') serverlib.env.append_value('LINKFLAGS', '-single_module') if bld.env['IS_SUN']: serverlib.env.append_value('LINKFLAGS', '-lnsl -lsocket') if bld.env['BUILD_NETLIB']: netlib = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) if bld.env['IS_MACOSX']: netlib.framework = ['CoreAudio'] netlib.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] netlib.includes = includes netlib.name = 'netlib' netlib.target = 'jacknet' netlib.use = ['SAMPLERATE', 'CELT', 'OPUS', 'PTHREAD'] if bld.env['IS_WINDOWS']: netlib.env['cxxshlib_PATTERN'] = 'lib%s.dll' netlib.install_path = '${BINDIR}' netlib.use += ['WS2_32', 'WINMM'] elif bld.env['IS_MACOSX']: netlib.install_path = '${LIBDIR}' else: netlib.use += ['RT'] netlib.install_path = '${LIBDIR}' netlib.source = [ 'JackNetAPI.cpp', 'JackNetInterface.cpp', 'JackNetTool.cpp', 'JackException.cpp', 'JackAudioAdapterInterface.cpp', 'JackLibSampleRateResampler.cpp', 'JackResampler.cpp', 'JackGlobals.cpp', 'ringbuffer.c'] if bld.env['IS_LINUX']: netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../posix/JackPosixMutex.cpp', '../linux/JackLinuxTime.c'] netlib.env.append_value('CPPFLAGS', '-fvisibility=hidden') if bld.env['IS_SUN']: netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../posix/JackPosixMutex.cpp', '../solaris/JackSolarisTime.c'] netlib.env.append_value('CPPFLAGS', '-fvisibility=hidden') if bld.env['IS_MACOSX']: netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../posix/JackPosixMutex.cpp', '../macosx/JackMachThread.mm', '../macosx/JackMachTime.c'] netlib.env.append_value('LINKFLAGS', '-single_module') if bld.env['IS_WINDOWS']: netlib.source += ['../windows/JackNetWinSocket.cpp','../windows/JackWinThread.cpp', '../windows/JackMMCSS.cpp', '../windows/JackWinTime.c'] netlib.vnum = bld.env['JACK_API_VERSION'] create_jack_process_obj(bld, 'netmanager', 'JackNetManager.cpp', serverlib) create_jack_process_obj(bld, 'profiler', 'JackProfiler.cpp', serverlib) net_adapter_sources = [ 'JackResampler.cpp', 'JackLibSampleRateResampler.cpp', 'JackAudioAdapter.cpp', 'JackAudioAdapterInterface.cpp', 'JackNetAdapter.cpp', ] if bld.env['BUILD_ADAPTER']: process = create_jack_process_obj(bld, 'netadapter', net_adapter_sources, serverlib) process.use += ['SAMPLERATE'] audio_adapter_sources = [ 'JackResampler.cpp', 'JackLibSampleRateResampler.cpp', 'JackAudioAdapter.cpp', 'JackAudioAdapterInterface.cpp', 'JackAudioAdapterFactory.cpp', ] if bld.env['BUILD_ADAPTER'] and bld.env['IS_MACOSX']: audio_adapter_sources += ['../macosx/coreaudio/JackCoreAudioAdapter.mm'] process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib, framework = [ 'CoreAudio', 'AudioUnit', 'AudioToolbox', 'CoreServices' ] ) process.use += ['SAMPLERATE'] if bld.env['BUILD_ADAPTER'] and bld.env['IS_LINUX'] and bld.env['BUILD_DRIVER_ALSA']: audio_adapter_sources += ['../linux/alsa/JackAlsaAdapter.cpp'] process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib) process.use = ['ALSA', 'SAMPLERATE'] if bld.env['BUILD_ADAPTER'] and bld.env['IS_SUN']: audio_adapter_sources += ['../solaris/oss/JackOSSAdapter.cpp', 'memops.c'] process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib) process.use = 'SAMPLERATE' if bld.env['BUILD_ADAPTER'] and bld.env['IS_WINDOWS']: audio_adapter_sources += ['../windows/portaudio/JackPortAudioAdapter.cpp', '../windows/portaudio/JackPortAudioDevices.cpp'] process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib) process.use += ['SAMPLERATE', 'PORTAUDIO'] bld.install_files('${PREFIX}/include/jack', bld.path.ant_glob('jack/*.h')) # process jack.pc.in -> jack.pc obj = bld( features = 'subst_pc', source = '../jack.pc.in', target = 'jack.pc', install_path = '${LIBDIR}/pkgconfig/', INCLUDEDIR = os.path.normpath(bld.env['PREFIX'] + '/include'), SERVERLIB = serverlib.target, ) 1.9.12~dfsg/common/JackError.cpp0000644000000000000000000000677313214314510015233 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2008 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "JackError.h" #include "JackGlobals.h" #include "JackMessageBuffer.h" using namespace Jack; static bool change_thread_log_function(jack_log_function_t log_function) { return (jack_tls_get(JackGlobals::fKeyLogFunction) == NULL && jack_tls_set(JackGlobals::fKeyLogFunction, (void*)log_function)); } SERVER_EXPORT int set_threaded_log_function() { return change_thread_log_function(JackMessageBufferAdd); } void jack_log_function(int level, const char *message) { void (* log_callback)(const char *); switch (level) { case LOG_LEVEL_INFO: log_callback = jack_info_callback; break; case LOG_LEVEL_ERROR: log_callback = jack_error_callback; break; default: return; } log_callback(message); } static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) { char buffer[256]; size_t len; jack_log_function_t log_function; if (prefix != NULL) { len = strlen(prefix); assert(len < 256); memcpy(buffer, prefix, len); } else { len = 0; } vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap); log_function = (jack_log_function_t)jack_tls_get(JackGlobals::fKeyLogFunction); /* if log function is not overriden for thread, use default one */ if (log_function == NULL) { log_function = jack_log_function; //log_function(LOG_LEVEL_INFO, "------ Using default log function"); } else { //log_function(LOG_LEVEL_INFO, "++++++ Using thread-specific log function"); } log_function(level, buffer); } SERVER_EXPORT void jack_error(const char *fmt, ...) { va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_ERROR, NULL, fmt, ap); va_end(ap); } SERVER_EXPORT void jack_info(const char *fmt, ...) { va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_INFO, NULL, fmt, ap); va_end(ap); } SERVER_EXPORT void jack_log(const char *fmt,...) { if (JackGlobals::fVerbose) { va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); va_end(ap); } } SERVER_EXPORT void default_jack_error_callback(const char *desc) { fprintf(stderr, "%s\n", desc); fflush(stderr); } SERVER_EXPORT void default_jack_info_callback(const char *desc) { fprintf(stdout, "%s\n", desc); fflush(stdout); } SERVER_EXPORT void silent_jack_error_callback(const char *desc) {} SERVER_EXPORT void silent_jack_info_callback(const char *desc) {} SERVER_EXPORT void (*jack_error_callback)(const char *desc) = &default_jack_error_callback; SERVER_EXPORT void (*jack_info_callback)(const char *desc) = &default_jack_info_callback; 1.9.12~dfsg/common/JackGlobals.cpp0000644000000000000000000000530313214314510015511 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackGlobals.h" namespace Jack { bool JackGlobals::fVerbose = 0; jack_tls_key JackGlobals::fRealTimeThread; static bool gKeyRealtimeThreadInitialized = jack_tls_allocate_key(&JackGlobals::fRealTimeThread); jack_tls_key JackGlobals::fNotificationThread; static bool gKeyNotificationThreadInitialized = jack_tls_allocate_key(&JackGlobals::fNotificationThread); jack_tls_key JackGlobals::fKeyLogFunction; static bool fKeyLogFunctionInitialized = jack_tls_allocate_key(&JackGlobals::fKeyLogFunction); JackMutex* JackGlobals::fOpenMutex = new JackMutex(); JackMutex* JackGlobals::fSynchroMutex = new JackMutex(); volatile bool JackGlobals::fServerRunning = false; JackClient* JackGlobals::fClientTable[CLIENT_NUM] = {}; #ifndef WIN32 jack_thread_creator_t JackGlobals::fJackThreadCreator = pthread_create; #endif #ifdef __CLIENTDEBUG__ std::ofstream* JackGlobals::fStream = NULL; void JackGlobals::CheckContext(const char* name) { if (JackGlobals::fStream == NULL) { char provstr[256]; char buffer[256]; time_t curtime; struct tm *loctime; /* Get the current time. */ curtime = time (NULL); /* Convert it to local time representation. */ loctime = localtime (&curtime); strftime(buffer, 256, "%I-%M", loctime); snprintf(provstr, sizeof(provstr), "JackAPICall-%s.log", buffer); JackGlobals::fStream = new std::ofstream(provstr, std::ios_base::ate); JackGlobals::fStream->is_open(); } #ifdef PTHREAD_WIN32 /* Added by JE - 10-10-2011 */ (*fStream) << "JACK API call : " << name << ", calling thread : " << pthread_self().p << std::endl; #elif defined(WIN32) && !defined(__CYGWIN__) (*fStream) << "JACK API call : " << name << ", calling thread : " << GetCurrentThread() << std::endl; #else (*fStream) << "JACK API call : " << name << ", calling thread : " << pthread_self() << std::endl; #endif } #else void JackGlobals::CheckContext(const char* name) {} #endif } // end of namespace 1.9.12~dfsg/common/JackDummyDriver.h0000644000000000000000000000266213214314510016047 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackDummyDriver__ #define __JackDummyDriver__ #include "JackTimedDriver.h" namespace Jack { /*! \brief The dummy driver. */ class JackDummyDriver : public JackTimedDriver { public: JackDummyDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackTimedDriver(name, alias, engine, table) {} virtual ~JackDummyDriver() {} virtual int Process() { JackDriver::CycleTakeBeginTime(); if (JackAudioDriver::Process() < 0) { return -1; } else { ProcessWait(); return 0; } } }; } // end of namespace #endif 1.9.12~dfsg/common/JackEngineProfiling.cpp0000644000000000000000000004232413214314510017211 0ustar rootroot/* Copyright (C) 2008 Grame & RTL This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackEngineProfiling.h" #include "JackGraphManager.h" #include "JackClientControl.h" #include "JackEngineControl.h" #include "JackClientInterface.h" #include "JackGlobals.h" #include "JackTime.h" #include #include namespace Jack { JackEngineProfiling::JackEngineProfiling():fAudioCycle(0),fMeasuredClient(0) { jack_info("Engine profiling activated, beware %ld MBytes are needed to record profiling points...", sizeof(fProfileTable) / (1024 * 1024)); // Force memory page in memset(fProfileTable, 0, sizeof(fProfileTable)); } JackEngineProfiling::~JackEngineProfiling() { std::ofstream fStream("JackEngineProfiling.log", std::ios_base::ate); jack_info("Write server and clients timing data..."); if (!fStream.is_open()) { jack_error("JackEngineProfiling::Save cannot open JackEngineProfiling.log file"); } else { // For each measured point for (int i = 2; i < TIME_POINTS; i++) { // Driver timing values long d1 = long(fProfileTable[i].fCurCycleBegin - fProfileTable[i - 1].fCurCycleBegin); long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin); if (d1 <= 0 || fProfileTable[i].fAudioCycle <= 0) continue; // Skip non valid cycles // Print driver delta and end cycle fStream << d1 << "\t" << d2 << "\t"; // For each measured client for (unsigned int j = 0; j < fMeasuredClient; j++) { int ref = fIntervalTable[j].fRefNum; // Is valid client cycle if (fProfileTable[i].fClientTable[ref].fStatus != NotTriggered) { long d5 = long(fProfileTable[i].fClientTable[ref].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); long d6 = long(fProfileTable[i].fClientTable[ref].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); long d7 = long(fProfileTable[i].fClientTable[ref].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin); fStream << ref << "\t" ; fStream << ((d5 > 0) ? d5 : 0) << "\t"; fStream << ((d6 > 0) ? d6 : 0) << "\t" ; fStream << ((d7 > 0) ? d7 : 0) << "\t"; fStream << ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0) << "\t" ; fStream << ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0) << "\t" ; fStream << fProfileTable[i].fClientTable[ref].fStatus << "\t" ;; } else { // Print tabs fStream << "\t \t \t \t \t \t \t"; } } // Terminate line fStream << std::endl; } } // Driver period std::ofstream fStream1("Timing1.plot", std::ios_base::ate); if (!fStream1.is_open()) { jack_error("JackEngineProfiling::Save cannot open Timing1.plot file"); } else { fStream1 << "set grid\n"; fStream1 << "set title \"Audio driver timing\"\n"; fStream1 << "set xlabel \"audio cycles\"\n"; fStream1 << "set ylabel \"usec\"\n"; fStream1 << "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"; fStream1 << "set output 'Timing1.svg\n"; fStream1 << "set terminal svg\n"; fStream1 << "set grid\n"; fStream1 << "set title \"Audio driver timing\"\n"; fStream1 << "set xlabel \"audio cycles\"\n"; fStream1 << "set ylabel \"usec\"\n"; fStream1 << "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"; fStream1 << "unset output\n"; } // Driver end date std::ofstream fStream2("Timing2.plot", std::ios_base::ate); if (!fStream2.is_open()) { jack_error("JackEngineProfiling::Save cannot open Timing2.plot file"); } else { fStream2 << "set grid\n"; fStream2 << "set title \"Driver end date\"\n"; fStream2 << "set xlabel \"audio cycles\"\n"; fStream2 << "set ylabel \"usec\"\n"; fStream2 << "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"; fStream2 << "set output 'Timing2.svg\n"; fStream2 << "set terminal svg\n"; fStream2 << "set grid\n"; fStream2 << "set title \"Driver end date\"\n"; fStream2 << "set xlabel \"audio cycles\"\n"; fStream2 << "set ylabel \"usec\"\n"; fStream2 << "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"; fStream2 << "unset output\n"; } // Clients end date if (fMeasuredClient > 0) { std::ofstream fStream3("Timing3.plot", std::ios_base::ate); if (!fStream3.is_open()) { jack_error("JackEngineProfiling::Save cannot open Timing3.plot file"); } else { fStream3 << "set multiplot\n"; fStream3 << "set grid\n"; fStream3 << "set title \"Clients end date\"\n"; fStream3 << "set xlabel \"audio cycles\"\n"; fStream3 << "set ylabel \"usec\"\n"; fStream3 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { if (i + 1 == fMeasuredClient) { // Last client fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; fStream3 << ((i + 1) * 7) - 1; fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines"; } else { fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; fStream3 << ((i + 1) * 7) - 1; fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines,"; } } else if (i + 1 == fMeasuredClient) { // Last client fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } } fStream3 << "\n unset multiplot\n"; fStream3 << "set output 'Timing3.svg\n"; fStream3 << "set terminal svg\n"; fStream3 << "set multiplot\n"; fStream3 << "set grid\n"; fStream3 << "set title \"Clients end date\"\n"; fStream3 << "set xlabel \"audio cycles\"\n"; fStream3 << "set ylabel \"usec\"\n"; fStream3 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { if ((i + 1) == fMeasuredClient) { // Last client fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; fStream3 << ((i + 1) * 7) - 1; fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines"; } else { fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; fStream3 << ((i + 1) * 7) - 1; fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines,"; } } else if ((i + 1) == fMeasuredClient) { // Last client fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } } fStream3 << "\nunset multiplot\n"; fStream3 << "unset output\n"; } } // Clients scheduling if (fMeasuredClient > 0) { std::ofstream fStream4("Timing4.plot", std::ios_base::ate); if (!fStream4.is_open()) { jack_error("JackEngineProfiling::Save cannot open Timing4.plot file"); } else { fStream4 << "set multiplot\n"; fStream4 << "set grid\n"; fStream4 << "set title \"Clients scheduling latency\"\n"; fStream4 << "set xlabel \"audio cycles\"\n"; fStream4 << "set ylabel \"usec\"\n"; fStream4 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if ((i + 1) == fMeasuredClient) { // Last client fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } } fStream4 << "\n unset multiplot\n"; fStream4 << "set output 'Timing4.svg\n"; fStream4 << "set terminal svg\n"; fStream4 << "set multiplot\n"; fStream4 << "set grid\n"; fStream4 << "set title \"Clients scheduling latency\"\n"; fStream4 << "set xlabel \"audio cycles\"\n"; fStream4 << "set ylabel \"usec\"\n"; fStream4 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if ((i + 1) == fMeasuredClient) { // Last client fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } } fStream4 << "\nunset multiplot\n"; fStream4 << "unset output\n"; } } // Clients duration if (fMeasuredClient > 0) { std::ofstream fStream5("Timing5.plot", std::ios_base::ate); if (!fStream5.is_open()) { jack_error("JackEngineProfiling::Save cannot open Timing5.plot file"); } else { fStream5 << "set multiplot\n"; fStream5 << "set grid\n"; fStream5 << "set title \"Clients duration\"\n"; fStream5 << "set xlabel \"audio cycles\"\n"; fStream5 << "set ylabel \"usec\"\n"; fStream5 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if ((i + 1) == fMeasuredClient) { // Last client fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } } fStream5 << "\n unset multiplot\n"; fStream5 << "set output 'Timing5.svg\n"; fStream5 << "set terminal svg\n"; fStream5 << "set multiplot\n"; fStream5 << "set grid\n"; fStream5 << "set title \"Clients duration\"\n"; fStream5 << "set xlabel \"audio cycles\"\n"; fStream5 << "set ylabel \"usec\"\n"; fStream5 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if ((i + 1) == fMeasuredClient) {// Last client fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } } fStream5 << "\nunset multiplot\n"; fStream5 << "unset output\n"; } } std::ofstream fStream6("Timings.html", std::ios_base::ate); if (!fStream6.is_open()) { jack_error("JackEngineProfiling::Save cannot open Timings.html file"); } else { fStream6 << "\n"; fStream6 << "\n"; fStream6 << "\n"; fStream6 << " \n"; fStream6 << " JACK engine profiling\n"; fStream6 << " \n"; fStream6 << " \n"; fStream6 << " \n"; fStream6 << " \n"; fStream6 << "

JACK engine profiling

\n"; fStream6 << "
Timing1
"; fStream6 << "
Timing2
"; fStream6 << "
Timing3
"; fStream6 << "
Timing4
"; fStream6 << "
Timing5
"; fStream6 << " \n"; fStream6 << "\n"; } std::ofstream fStream7("generate_timings", std::ios_base::ate); if (!fStream7.is_open()) { jack_error("JackEngineProfiling::Save cannot open generate_timings file"); } else { fStream7 << "gnuplot -persist Timing1.plot \n"; fStream7 << "gnuplot -persist Timing2.plot\n"; fStream7 << "gnuplot -persist Timing3.plot\n"; fStream7 << "gnuplot -persist Timing4.plot\n"; fStream7 << "gnuplot -persist Timing5.plot\n"; } } bool JackEngineProfiling::CheckClient(const char* name, int cur_point) { for (int i = 0; i < MEASURED_CLIENTS; i++) { if (strcmp(fIntervalTable[i].fName, name) == 0) { fIntervalTable[i].fEndInterval = cur_point; return true; } } return false; } void JackEngineProfiling::Profile(JackClientInterface** table, JackGraphManager* manager, jack_time_t period_usecs, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { fAudioCycle = (fAudioCycle + 1) % TIME_POINTS; // Keeps cycle data fProfileTable[fAudioCycle].fPeriodUsecs = period_usecs; fProfileTable[fAudioCycle].fCurCycleBegin = cur_cycle_begin; fProfileTable[fAudioCycle].fPrevCycleEnd = prev_cycle_end; fProfileTable[fAudioCycle].fAudioCycle = fAudioCycle; for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; JackClientTiming* timing = manager->GetClientTiming(i); if (client && client->GetClientControl()->fActive && client->GetClientControl()->fCallback[kRealTimeCallback]) { if (!CheckClient(client->GetClientControl()->fName, fAudioCycle)) { // Keep new measured client fIntervalTable[fMeasuredClient].fRefNum = i; strcpy(fIntervalTable[fMeasuredClient].fName, client->GetClientControl()->fName); fIntervalTable[fMeasuredClient].fBeginInterval = fAudioCycle; fIntervalTable[fMeasuredClient].fEndInterval = fAudioCycle; fMeasuredClient++; } fProfileTable[fAudioCycle].fClientTable[i].fRefNum = i; fProfileTable[fAudioCycle].fClientTable[i].fSignaledAt = timing->fSignaledAt; fProfileTable[fAudioCycle].fClientTable[i].fAwakeAt = timing->fAwakeAt; fProfileTable[fAudioCycle].fClientTable[i].fFinishedAt = timing->fFinishedAt; fProfileTable[fAudioCycle].fClientTable[i].fStatus = timing->fStatus; } } } JackTimingMeasure* JackEngineProfiling::GetCurMeasure() { return &fProfileTable[fAudioCycle]; } } // end of namespace 1.9.12~dfsg/common/JackControlAPI.cpp0000644000000000000000000012007513214314510016104 0ustar rootroot// u/* -*- Mode: C++ ; c-basic-offset: 4 -*- */ /* JACK control API implementation Copyright (C) 2008 Nedko Arnaudov Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef WIN32 #include #include #include #endif #include "types.h" #include #include #include #include #include #include "jslist.h" #include "driver_interface.h" #include "JackError.h" #include "JackServer.h" #include "shm.h" #include "JackTools.h" #include "JackControlAPI.h" #include "JackLockedEngine.h" #include "JackConstants.h" #include "JackDriverLoader.h" #include "JackServerGlobals.h" using namespace Jack; /* JackEngine::CheckPortsConnect() has some assumptions about char values */ static struct jack_constraint_enum_char_descriptor self_connect_mode_constraint_descr_array[] = { { ' ', "Don't restrict self connect requests" }, { 'E', "Fail self connect requests to external ports only" }, { 'e', "Ignore self connect requests to external ports only" }, { 'A', "Fail all self connect requests" }, { 'a', "Ignore all self connect requests" }, { 0 } }; struct jackctl_server { JSList * drivers; JSList * internals; JSList * parameters; class JackServer * engine; /* string, server name */ union jackctl_parameter_value name; union jackctl_parameter_value default_name; /* bool, whether to be "realtime" */ union jackctl_parameter_value realtime; union jackctl_parameter_value default_realtime; /* int32_t */ union jackctl_parameter_value realtime_priority; union jackctl_parameter_value default_realtime_priority; /* bool, whether to exit once all clients have closed their connections */ union jackctl_parameter_value temporary; union jackctl_parameter_value default_temporary; /* bool, whether to be verbose */ union jackctl_parameter_value verbose; union jackctl_parameter_value default_verbose; /* int32_t, msecs; if zero, use period size. */ union jackctl_parameter_value client_timeout; union jackctl_parameter_value default_client_timeout; /* uint32_t, clock source type */ union jackctl_parameter_value clock_source; union jackctl_parameter_value default_clock_source; /* uint32_t, max port number */ union jackctl_parameter_value port_max; union jackctl_parameter_value default_port_max; /* bool */ union jackctl_parameter_value replace_registry; union jackctl_parameter_value default_replace_registry; /* bool, synchronous or asynchronous engine mode */ union jackctl_parameter_value sync; union jackctl_parameter_value default_sync; /* char enum, self connect mode mode */ union jackctl_parameter_value self_connect_mode; union jackctl_parameter_value default_self_connect_mode; }; struct jackctl_driver { jack_driver_desc_t * desc_ptr; JSList * parameters; JSList * infos; }; struct jackctl_internal { jack_driver_desc_t * desc_ptr; JSList * parameters; int refnum; }; struct jackctl_parameter { const char * name; const char * short_description; const char * long_description; jackctl_param_type_t type; bool is_set; union jackctl_parameter_value * value_ptr; union jackctl_parameter_value * default_value_ptr; union jackctl_parameter_value value; union jackctl_parameter_value default_value; struct jackctl_driver * driver_ptr; char id; jack_driver_param_constraint_desc_t * constraint_ptr; }; const char * jack_get_self_connect_mode_description(char mode) { struct jack_constraint_enum_char_descriptor * descr_ptr; for (descr_ptr = self_connect_mode_constraint_descr_array; descr_ptr->value; descr_ptr++) if (descr_ptr->value == mode) return descr_ptr->short_desc; return NULL; } static struct jackctl_parameter * jackctl_add_parameter( JSList ** parameters_list_ptr_ptr, const char * name, const char * short_description, const char * long_description, jackctl_param_type_t type, union jackctl_parameter_value * value_ptr, union jackctl_parameter_value * default_value_ptr, union jackctl_parameter_value value, jack_driver_param_constraint_desc_t * constraint_ptr = NULL) { struct jackctl_parameter * parameter_ptr; parameter_ptr = (struct jackctl_parameter *)malloc(sizeof(struct jackctl_parameter)); if (parameter_ptr == NULL) { jack_error("Cannot allocate memory for jackctl_parameter structure."); goto fail; } parameter_ptr->name = name; parameter_ptr->short_description = short_description; parameter_ptr->long_description = long_description; parameter_ptr->type = type; parameter_ptr->is_set = false; if (value_ptr == NULL) { value_ptr = ¶meter_ptr->value; } if (default_value_ptr == NULL) { default_value_ptr = ¶meter_ptr->default_value; } parameter_ptr->value_ptr = value_ptr; parameter_ptr->default_value_ptr = default_value_ptr; *value_ptr = *default_value_ptr = value; parameter_ptr->driver_ptr = NULL; parameter_ptr->id = 0; parameter_ptr->constraint_ptr = constraint_ptr; *parameters_list_ptr_ptr = jack_slist_append(*parameters_list_ptr_ptr, parameter_ptr); return parameter_ptr; fail: return NULL; } static void jackctl_free_driver_parameters( struct jackctl_driver * driver_ptr) { JSList * next_node_ptr; while (driver_ptr->parameters) { next_node_ptr = driver_ptr->parameters->next; free(driver_ptr->parameters->data); free(driver_ptr->parameters); driver_ptr->parameters = next_node_ptr; } } static bool jackctl_add_driver_parameters( struct jackctl_driver * driver_ptr) { unsigned int i; union jackctl_parameter_value jackctl_value; jackctl_param_type_t jackctl_type; struct jackctl_parameter * parameter_ptr; jack_driver_param_desc_t * descriptor_ptr; for (i = 0 ; i < driver_ptr->desc_ptr->nparams ; i++) { descriptor_ptr = driver_ptr->desc_ptr->params + i; switch (descriptor_ptr->type) { case JackDriverParamInt: jackctl_type = JackParamInt; jackctl_value.i = descriptor_ptr->value.i; break; case JackDriverParamUInt: jackctl_type = JackParamUInt; jackctl_value.ui = descriptor_ptr->value.ui; break; case JackDriverParamChar: jackctl_type = JackParamChar; jackctl_value.c = descriptor_ptr->value.c; break; case JackDriverParamString: jackctl_type = JackParamString; strcpy(jackctl_value.str, descriptor_ptr->value.str); break; case JackDriverParamBool: jackctl_type = JackParamBool; jackctl_value.b = descriptor_ptr->value.i; break; default: jack_error("Unknown driver parameter type %i", (int)descriptor_ptr->type); assert(0); goto fail; } parameter_ptr = jackctl_add_parameter( &driver_ptr->parameters, descriptor_ptr->name, descriptor_ptr->short_desc, descriptor_ptr->long_desc, jackctl_type, NULL, NULL, jackctl_value, descriptor_ptr->constraint); if (parameter_ptr == NULL) { goto fail; } parameter_ptr->driver_ptr = driver_ptr; parameter_ptr->id = descriptor_ptr->character; } return true; fail: jackctl_free_driver_parameters(driver_ptr); return false; } /* destroy jack_driver_param_desc_t list created by jackctl_create_param_list() */ static void jackctl_destroy_param_list( JSList * params) { JSList * next; while (params) { next = params->next; free(params->data); free(params); params = next; } } /* for drivers and internals are configured through jack_driver_param_t JSList */ /* this function creates such list from a jackctl_parameter list */ static bool jackctl_create_param_list( const JSList * paramlist, JSList ** retparamlist) { jackctl_parameter * param_ptr; jack_driver_param_t * retparam_ptr; *retparamlist = NULL; while (paramlist != NULL) { param_ptr = (jackctl_parameter *)paramlist->data; if (param_ptr->is_set) { /* jack_info("setting driver parameter %p ...", parameter_ptr); */ retparam_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t)); if (retparam_ptr == NULL) { jack_error ("Allocation of jack_driver_param_t structure failed"); goto destroy; } retparam_ptr->character = param_ptr->id; switch (param_ptr->type) { case JackParamInt: retparam_ptr->value.i = param_ptr->value_ptr->i; break; case JackParamUInt: retparam_ptr->value.ui = param_ptr->value_ptr->ui; break; case JackParamChar: retparam_ptr->value.c = param_ptr->value_ptr->c; break; case JackParamString: strcpy(retparam_ptr->value.str, param_ptr->value_ptr->str); break; case JackParamBool: retparam_ptr->value.i = param_ptr->value_ptr->b; break; default: jack_error("Unknown parameter type %i", (int)param_ptr->type); assert(0); goto free; } *retparamlist = jack_slist_append(*retparamlist, retparam_ptr); } paramlist = paramlist->next; } return true; free: free(retparam_ptr); destroy: jackctl_destroy_param_list(*retparamlist); return false; } static int jackctl_drivers_load( struct jackctl_server * server_ptr) { struct jackctl_driver * driver_ptr; JSList *node_ptr; JSList *descriptor_node_ptr; descriptor_node_ptr = jack_drivers_load(NULL); if (descriptor_node_ptr == NULL) { jack_error("Could not find any drivers in driver directory!"); return false; } while (descriptor_node_ptr != NULL) { driver_ptr = (struct jackctl_driver *)malloc(sizeof(struct jackctl_driver)); if (driver_ptr == NULL) { jack_error("Memory allocation of jackctl_driver structure failed."); goto next; } driver_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data; driver_ptr->parameters = NULL; driver_ptr->infos = NULL; if (!jackctl_add_driver_parameters(driver_ptr)) { assert(driver_ptr->parameters == NULL); free(driver_ptr); goto next; } server_ptr->drivers = jack_slist_append(server_ptr->drivers, driver_ptr); next: node_ptr = descriptor_node_ptr; descriptor_node_ptr = descriptor_node_ptr->next; free(node_ptr); } return true; } static void jackctl_server_free_drivers( struct jackctl_server * server_ptr) { JSList * next_node_ptr; struct jackctl_driver * driver_ptr; while (server_ptr->drivers) { next_node_ptr = server_ptr->drivers->next; driver_ptr = (struct jackctl_driver *)server_ptr->drivers->data; jackctl_free_driver_parameters(driver_ptr); free(driver_ptr->desc_ptr->params); free(driver_ptr->desc_ptr); free(driver_ptr); free(server_ptr->drivers); server_ptr->drivers = next_node_ptr; } } static int jackctl_internals_load( struct jackctl_server * server_ptr) { struct jackctl_internal * internal_ptr; JSList *node_ptr; JSList *descriptor_node_ptr; descriptor_node_ptr = jack_internals_load(NULL); if (descriptor_node_ptr == NULL) { jack_error("Could not find any internals in driver directory!"); return false; } while (descriptor_node_ptr != NULL) { internal_ptr = (struct jackctl_internal *)malloc(sizeof(struct jackctl_internal)); if (internal_ptr == NULL) { jack_error("Memory allocation of jackctl_driver structure failed."); goto next; } internal_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data; internal_ptr->parameters = NULL; internal_ptr->refnum = -1; if (!jackctl_add_driver_parameters((struct jackctl_driver *)internal_ptr)) { assert(internal_ptr->parameters == NULL); free(internal_ptr); goto next; } server_ptr->internals = jack_slist_append(server_ptr->internals, internal_ptr); next: node_ptr = descriptor_node_ptr; descriptor_node_ptr = descriptor_node_ptr->next; free(node_ptr); } return true; } static void jackctl_server_free_internals( struct jackctl_server * server_ptr) { JSList * next_node_ptr; struct jackctl_internal * internal_ptr; while (server_ptr->internals) { next_node_ptr = server_ptr->internals->next; internal_ptr = (struct jackctl_internal *)server_ptr->internals->data; jackctl_free_driver_parameters((struct jackctl_driver *)internal_ptr); free(internal_ptr->desc_ptr->params); free(internal_ptr->desc_ptr); free(internal_ptr); free(server_ptr->internals); server_ptr->internals = next_node_ptr; } } static void jackctl_server_free_parameters( struct jackctl_server * server_ptr) { JSList * next_node_ptr; while (server_ptr->parameters) { next_node_ptr = server_ptr->parameters->next; free(server_ptr->parameters->data); free(server_ptr->parameters); server_ptr->parameters = next_node_ptr; } } #ifdef WIN32 struct jackctl_sigmask { HANDLE wait_event; }; static jackctl_sigmask sigmask; static void signal_handler(int signum) { printf("Jack main caught signal %d\n", signum); (void) signal(SIGINT, SIG_DFL); SetEvent(sigmask.wait_event); } jackctl_sigmask_t * jackctl_setup_signals( unsigned int flags) { if ((sigmask.wait_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) { jack_error("CreateEvent fails err = %ld", GetLastError()); return 0; } (void) signal(SIGINT, signal_handler); (void) signal(SIGABRT, signal_handler); (void) signal(SIGTERM, signal_handler); return &sigmask; } void jackctl_wait_signals(jackctl_sigmask_t * signals) { if (WaitForSingleObject(signals->wait_event, INFINITE) != WAIT_OBJECT_0) { jack_error("WaitForSingleObject fails err = %ld", GetLastError()); } } #else struct jackctl_sigmask { sigset_t signals; }; static jackctl_sigmask sigmask; static void signal_handler(int sig) { /* this is used by the child (active) process, but it never gets called unless we are already shutting down after another signal. */ char buf[64]; snprintf(buf, sizeof(buf), "Received signal %d during shutdown (ignored)\n", sig); } SERVER_EXPORT jackctl_sigmask_t * jackctl_setup_signals( unsigned int flags) { sigset_t allsignals; struct sigaction action; int i; /* ensure that we are in our own process group so that kill (SIG, -pgrp) does the right thing. */ setsid(); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); /* what's this for? POSIX says that signals are delivered like this: * if a thread has blocked that signal, it is not a candidate to receive the signal. * of all threads not blocking the signal, pick one at random, and deliver the signal. this means that a simple-minded multi-threaded program can expect to get POSIX signals delivered randomly to any one of its threads, here, we block all signals that we think we might receive and want to catch. all "child" threads will inherit this setting. if we create a thread that calls sigwait() on the same set of signals, implicitly unblocking all those signals. any of those signals that are delivered to the process will be delivered to that thread, and that thread alone. this makes cleanup for a signal-driven exit much easier, since we know which thread is doing it and more importantly, we are free to call async-unsafe functions, because the code is executing in normal thread context after a return from sigwait(). */ sigemptyset(&sigmask.signals); sigaddset(&sigmask.signals, SIGHUP); sigaddset(&sigmask.signals, SIGINT); sigaddset(&sigmask.signals, SIGQUIT); sigaddset(&sigmask.signals, SIGPIPE); sigaddset(&sigmask.signals, SIGTERM); #ifndef __ANDROID__ /* android's bionic c doesn't provide pthread_cancel() and related functions. * to solve this issue, use pthread_kill() & SIGUSR1 instead. */ sigaddset(&sigmask.signals, SIGUSR1); #endif sigaddset(&sigmask.signals, SIGUSR2); /* all child threads will inherit this mask unless they * explicitly reset it */ pthread_sigmask(SIG_BLOCK, &sigmask.signals, 0); /* install a do-nothing handler because otherwise pthreads behaviour is undefined when we enter sigwait. */ sigfillset(&allsignals); action.sa_handler = signal_handler; action.sa_mask = allsignals; action.sa_flags = SA_RESTART|SA_RESETHAND; for (i = 1; i < NSIG; i++) { if (sigismember (&sigmask.signals, i)) { sigaction(i, &action, 0); } } return &sigmask; } SERVER_EXPORT void jackctl_wait_signals(jackctl_sigmask_t * sigmask) { int sig; bool waiting = true; while (waiting) { #if defined(sun) && !defined(__sun__) // SUN compiler only, to check sigwait(&sigmask->signals); #else sigwait(&sigmask->signals, &sig); #endif fprintf(stderr, "Jack main caught signal %d\n", sig); switch (sig) { case SIGUSR1: //jack_dump_configuration(engine, 1); break; case SIGUSR2: // driver exit waiting = false; break; case SIGTTOU: break; default: waiting = false; break; } } if (sig != SIGSEGV) { // unblock signals so we can see them during shutdown. // this will help prod developers not to lose sight of // bugs that cause segfaults etc. during shutdown. sigprocmask(SIG_UNBLOCK, &sigmask->signals, 0); } } #endif static jack_driver_param_constraint_desc_t * get_realtime_priority_constraint() { jack_driver_param_constraint_desc_t * constraint_ptr; int min, max; if (!jack_get_thread_realtime_priority_range(&min, &max)) { return NULL; } //jack_info("realtime priority range is (%d,%d)", min, max); constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_constraint_desc_t)); if (constraint_ptr == NULL) { jack_error("Cannot allocate memory for jack_driver_param_constraint_desc_t structure."); return NULL; } constraint_ptr->flags = JACK_CONSTRAINT_FLAG_RANGE; constraint_ptr->constraint.range.min.i = min; constraint_ptr->constraint.range.max.i = max; return constraint_ptr; } SERVER_EXPORT jackctl_server_t * jackctl_server_create( bool (* on_device_acquire)(const char * device_name), void (* on_device_release)(const char * device_name)) { struct jackctl_server * server_ptr; union jackctl_parameter_value value; server_ptr = (struct jackctl_server *)malloc(sizeof(struct jackctl_server)); if (server_ptr == NULL) { jack_error("Cannot allocate memory for jackctl_server structure."); goto fail; } server_ptr->drivers = NULL; server_ptr->internals = NULL; server_ptr->parameters = NULL; server_ptr->engine = NULL; strcpy(value.str, JackTools::DefaultServerName()); if (jackctl_add_parameter( &server_ptr->parameters, "name", "Server name to use.", "", JackParamString, &server_ptr->name, &server_ptr->default_name, value) == NULL) { goto fail_free_parameters; } value.b = true; if (jackctl_add_parameter( &server_ptr->parameters, "realtime", "Whether to use realtime mode.", "Use realtime scheduling. This is needed for reliable low-latency performance. On most systems, it requires JACK to run with special scheduler and memory allocation privileges, which may be obtained in several ways. On Linux you should use PAM.", JackParamBool, &server_ptr->realtime, &server_ptr->default_realtime, value) == NULL) { goto fail_free_parameters; } value.i = 10; if (jackctl_add_parameter( &server_ptr->parameters, "realtime-priority", "Scheduler priority when running in realtime mode.", "", JackParamInt, &server_ptr->realtime_priority, &server_ptr->default_realtime_priority, value, get_realtime_priority_constraint()) == NULL) { goto fail_free_parameters; } value.b = false; if (jackctl_add_parameter( &server_ptr->parameters, "temporary", "Exit once all clients have closed their connections.", "", JackParamBool, &server_ptr->temporary, &server_ptr->default_temporary, value) == NULL) { goto fail_free_parameters; } value.b = false; if (jackctl_add_parameter( &server_ptr->parameters, "verbose", "Verbose mode.", "", JackParamBool, &server_ptr->verbose, &server_ptr->default_verbose, value) == NULL) { goto fail_free_parameters; } value.i = 0; if (jackctl_add_parameter( &server_ptr->parameters, "client-timeout", "Client timeout limit in milliseconds.", "", JackParamInt, &server_ptr->client_timeout, &server_ptr->default_client_timeout, value) == NULL) { goto fail_free_parameters; } value.ui = 0; if (jackctl_add_parameter( &server_ptr->parameters, "clock-source", "Clocksource type : c(ycle) | h(pet) | s(ystem).", "", JackParamUInt, &server_ptr->clock_source, &server_ptr->default_clock_source, value) == NULL) { goto fail_free_parameters; } value.ui = PORT_NUM; if (jackctl_add_parameter( &server_ptr->parameters, "port-max", "Maximum number of ports.", "", JackParamUInt, &server_ptr->port_max, &server_ptr->default_port_max, value) == NULL) { goto fail_free_parameters; } value.b = false; if (jackctl_add_parameter( &server_ptr->parameters, "replace-registry", "Replace shared memory registry.", "", JackParamBool, &server_ptr->replace_registry, &server_ptr->default_replace_registry, value) == NULL) { goto fail_free_parameters; } value.b = false; if (jackctl_add_parameter( &server_ptr->parameters, "sync", "Use server synchronous mode.", "", JackParamBool, &server_ptr->sync, &server_ptr->default_sync, value) == NULL) { goto fail_free_parameters; } value.c = JACK_DEFAULT_SELF_CONNECT_MODE; if (jackctl_add_parameter( &server_ptr->parameters, "self-connect-mode", "Self connect mode.", "Whether JACK clients are allowed to connect their own ports", JackParamChar, &server_ptr->self_connect_mode, &server_ptr->default_self_connect_mode, value, jack_constraint_compose_enum_char( JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE, self_connect_mode_constraint_descr_array)) == NULL) { goto fail_free_parameters; } JackServerGlobals::on_device_acquire = on_device_acquire; JackServerGlobals::on_device_release = on_device_release; if (!jackctl_drivers_load(server_ptr)) { goto fail_free_parameters; } /* Allowed to fail */ jackctl_internals_load(server_ptr); return server_ptr; fail_free_parameters: jackctl_server_free_parameters(server_ptr); free(server_ptr); fail: return NULL; } SERVER_EXPORT void jackctl_server_destroy(jackctl_server *server_ptr) { if (server_ptr) { jackctl_server_free_drivers(server_ptr); jackctl_server_free_internals(server_ptr); jackctl_server_free_parameters(server_ptr); free(server_ptr); } } SERVER_EXPORT const JSList * jackctl_server_get_drivers_list(jackctl_server *server_ptr) { return (server_ptr) ? server_ptr->drivers : NULL; } SERVER_EXPORT bool jackctl_server_stop(jackctl_server *server_ptr) { if (server_ptr) { server_ptr->engine->Stop(); return true; } else { return false; } } SERVER_EXPORT bool jackctl_server_close(jackctl_server *server_ptr) { if (server_ptr) { server_ptr->engine->Close(); delete server_ptr->engine; /* clean up shared memory and files from this server instance */ jack_log("Cleaning up shared memory"); jack_cleanup_shm(); jack_log("Cleaning up files"); JackTools::CleanupFiles(server_ptr->name.str); jack_log("Unregistering server `%s'", server_ptr->name.str); jack_unregister_server(server_ptr->name.str); server_ptr->engine = NULL; return true; } else { return false; } } SERVER_EXPORT const JSList * jackctl_server_get_parameters(jackctl_server *server_ptr) { return (server_ptr) ? server_ptr->parameters : NULL; } SERVER_EXPORT bool jackctl_server_open( jackctl_server *server_ptr, jackctl_driver *driver_ptr) { JSList * paramlist = NULL; try { if (!server_ptr || !driver_ptr) { return false; } int rc = jack_register_server(server_ptr->name.str, server_ptr->replace_registry.b); switch (rc) { case EEXIST: jack_error("`%s' server already active", server_ptr->name.str); goto fail; case ENOSPC: jack_error("Too many servers already active"); goto fail; case ENOMEM: jack_error("No access to shm registry"); goto fail; } jack_log("Server `%s' registered", server_ptr->name.str); /* clean up shared memory and files from any previous * instance of this server name */ jack_cleanup_shm(); JackTools::CleanupFiles(server_ptr->name.str); if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0) { server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ } /* check port max value before allocating server */ if (server_ptr->port_max.ui > PORT_NUM_MAX) { jack_error("Jack server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); goto fail; } /* get the engine/driver started */ server_ptr->engine = new JackServer( server_ptr->sync.b, server_ptr->temporary.b, server_ptr->client_timeout.i, server_ptr->realtime.b, server_ptr->realtime_priority.i, server_ptr->port_max.ui, server_ptr->verbose.b, (jack_timer_type_t)server_ptr->clock_source.ui, server_ptr->self_connect_mode.c, server_ptr->name.str); if (server_ptr->engine == NULL) { jack_error("Failed to create new JackServer object"); goto fail_unregister; } if (!jackctl_create_param_list(driver_ptr->parameters, ¶mlist)) goto fail_delete; rc = server_ptr->engine->Open(driver_ptr->desc_ptr, paramlist); jackctl_destroy_param_list(paramlist); if (rc < 0) { jack_error("JackServer::Open failed with %d", rc); goto fail_delete; } return true; } catch (std::exception e) { jack_error("jackctl_server_open error..."); jackctl_destroy_param_list(paramlist); } fail_delete: delete server_ptr->engine; server_ptr->engine = NULL; fail_unregister: jack_log("Cleaning up shared memory"); jack_cleanup_shm(); jack_log("Cleaning up files"); JackTools::CleanupFiles(server_ptr->name.str); jack_log("Unregistering server `%s'", server_ptr->name.str); jack_unregister_server(server_ptr->name.str); fail: return false; } SERVER_EXPORT bool jackctl_server_start( jackctl_server *server_ptr) { if (!server_ptr) { return false; } else { int rc = server_ptr->engine->Start(); bool result = rc >= 0; if (! result) { jack_error("JackServer::Start() failed with %d", rc); } return result; } } SERVER_EXPORT const char * jackctl_driver_get_name(jackctl_driver *driver_ptr) { return (driver_ptr) ? driver_ptr->desc_ptr->name : NULL; } SERVER_EXPORT jackctl_driver_type_t jackctl_driver_get_type(jackctl_driver *driver_ptr) { return (driver_ptr) ? (jackctl_driver_type_t)driver_ptr->desc_ptr->type : (jackctl_driver_type_t)0; } SERVER_EXPORT const JSList * jackctl_driver_get_parameters(jackctl_driver *driver_ptr) { return (driver_ptr) ? driver_ptr->parameters : NULL; } SERVER_EXPORT jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver *driver_ptr) { return (driver_ptr) ? driver_ptr->desc_ptr : NULL; } SERVER_EXPORT const char * jackctl_parameter_get_name(jackctl_parameter *parameter_ptr) { return (parameter_ptr) ? parameter_ptr->name : NULL; } SERVER_EXPORT const char * jackctl_parameter_get_short_description(jackctl_parameter *parameter_ptr) { return (parameter_ptr) ? parameter_ptr->short_description : NULL; } SERVER_EXPORT const char * jackctl_parameter_get_long_description(jackctl_parameter *parameter_ptr) { return (parameter_ptr) ? parameter_ptr->long_description : NULL; } SERVER_EXPORT bool jackctl_parameter_has_range_constraint(jackctl_parameter *parameter_ptr) { return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) != 0) : false; } SERVER_EXPORT bool jackctl_parameter_has_enum_constraint(jackctl_parameter *parameter_ptr) { return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) == 0): false; } SERVER_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter *parameter_ptr) { if (!parameter_ptr) { return 0; } if (!jackctl_parameter_has_enum_constraint(parameter_ptr)) { return 0; } return parameter_ptr->constraint_ptr->constraint.enumeration.count; } SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value(jackctl_parameter *parameter_ptr, uint32_t index) { jack_driver_param_value_t * value_ptr; union jackctl_parameter_value jackctl_value; if (!parameter_ptr) { memset(&jackctl_value, 0, sizeof(jackctl_value)); return jackctl_value; } value_ptr = ¶meter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].value; switch (parameter_ptr->type) { case JackParamInt: jackctl_value.i = value_ptr->i; break; case JackParamUInt: jackctl_value.ui = value_ptr->ui; break; case JackParamChar: jackctl_value.c = value_ptr->c; break; case JackParamString: strcpy(jackctl_value.str, value_ptr->str); break; default: jack_error("Bad driver parameter type %i (enum constraint)", (int)parameter_ptr->type); assert(0); } return jackctl_value; } SERVER_EXPORT const char * jackctl_parameter_get_enum_constraint_description(jackctl_parameter *parameter_ptr, uint32_t index) { return (parameter_ptr) ? parameter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].short_desc : NULL; } SERVER_EXPORT void jackctl_parameter_get_range_constraint(jackctl_parameter *parameter_ptr, union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr) { if (!parameter_ptr || !min_ptr || !max_ptr) { return; } switch (parameter_ptr->type) { case JackParamInt: min_ptr->i = parameter_ptr->constraint_ptr->constraint.range.min.i; max_ptr->i = parameter_ptr->constraint_ptr->constraint.range.max.i; return; case JackParamUInt: min_ptr->ui = parameter_ptr->constraint_ptr->constraint.range.min.ui; max_ptr->ui = parameter_ptr->constraint_ptr->constraint.range.max.ui; return; default: jack_error("Bad driver parameter type %i (range constraint)", (int)parameter_ptr->type); assert(0); } } SERVER_EXPORT bool jackctl_parameter_constraint_is_strict(jackctl_parameter_t * parameter_ptr) { return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_STRICT) != 0) : false; } SERVER_EXPORT bool jackctl_parameter_constraint_is_fake_value(jackctl_parameter_t * parameter_ptr) { return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE) != 0) : false; } SERVER_EXPORT jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter *parameter_ptr) { return (parameter_ptr) ? parameter_ptr->type : (jackctl_param_type_t)0; } SERVER_EXPORT char jackctl_parameter_get_id(jackctl_parameter_t * parameter_ptr) { return (parameter_ptr) ? parameter_ptr->id : 0; } SERVER_EXPORT bool jackctl_parameter_is_set(jackctl_parameter *parameter_ptr) { return (parameter_ptr) ? parameter_ptr->is_set : false; } SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter *parameter_ptr) { if (parameter_ptr) { return *parameter_ptr->value_ptr; } else { union jackctl_parameter_value jackctl_value; memset(&jackctl_value, 0, sizeof(jackctl_value)); return jackctl_value; } } SERVER_EXPORT bool jackctl_parameter_reset(jackctl_parameter *parameter_ptr) { if (!parameter_ptr) { return NULL; } if (!parameter_ptr->is_set) { return true; } parameter_ptr->is_set = false; *parameter_ptr->value_ptr = *parameter_ptr->default_value_ptr; return true; } SERVER_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, const union jackctl_parameter_value * value_ptr) { if (!parameter_ptr || !value_ptr) { return NULL; } parameter_ptr->is_set = true; *parameter_ptr->value_ptr = *value_ptr; return true; } SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter *parameter_ptr) { if (parameter_ptr) { return *parameter_ptr->default_value_ptr; } else { union jackctl_parameter_value jackctl_value; memset(&jackctl_value, 0, sizeof(jackctl_value)); return jackctl_value; } } // Internals clients SERVER_EXPORT const JSList * jackctl_server_get_internals_list(jackctl_server *server_ptr) { return (server_ptr) ? server_ptr->internals : NULL; } SERVER_EXPORT const char * jackctl_internal_get_name(jackctl_internal *internal_ptr) { return (internal_ptr) ? internal_ptr->desc_ptr->name : NULL; } SERVER_EXPORT const JSList * jackctl_internal_get_parameters(jackctl_internal *internal_ptr) { return (internal_ptr) ? internal_ptr->parameters : NULL; } SERVER_EXPORT bool jackctl_server_load_internal( jackctl_server * server_ptr, jackctl_internal * internal) { if (!server_ptr || !internal) { return false; } int status; if (server_ptr->engine != NULL) { JSList * paramlist; if (!jackctl_create_param_list(internal->parameters, ¶mlist)) return false; server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, paramlist, JackNullOption, &internal->refnum, -1, &status); jackctl_destroy_param_list(paramlist); return (internal->refnum > 0); } else { return false; } } SERVER_EXPORT bool jackctl_server_unload_internal( jackctl_server * server_ptr, jackctl_internal * internal) { if (!server_ptr || !internal) { return false; } int status; if (server_ptr->engine != NULL && internal->refnum > 0) { // Client object is internally kept in JackEngine, and will be deallocated in InternalClientUnload return ((server_ptr->engine->GetEngine()->InternalClientUnload(internal->refnum, &status)) == 0); } else { return false; } } SERVER_EXPORT bool jackctl_server_load_session_file( jackctl_server * server_ptr, const char * file) { if (!server_ptr || !file || !server_ptr->engine) { return false; } return (server_ptr->engine->LoadInternalSessionFile(file) >= 0); } SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr && server_ptr->engine) { if (server_ptr->engine->IsRunning()) { jack_error("Cannot add a slave in a running server"); return false; } else { JSList * paramlist; if (!jackctl_create_param_list(driver_ptr->parameters, ¶mlist)) return false; JackDriverInfo* info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, paramlist); jackctl_destroy_param_list(paramlist); if (info) { driver_ptr->infos = jack_slist_append(driver_ptr->infos, info); return true; } else { return false; } } } else { return false; } } SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr && server_ptr->engine) { if (server_ptr->engine->IsRunning()) { jack_error("Cannot remove a slave from a running server"); return false; } else { if (driver_ptr->infos) { JackDriverInfo* info = (JackDriverInfo*)driver_ptr->infos->data; assert(info); driver_ptr->infos = jack_slist_remove(driver_ptr->infos, info); server_ptr->engine->RemoveSlave(info); delete info; return true; } else { return false; } } } else { return false; } } SERVER_EXPORT bool jackctl_server_switch_master(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr && server_ptr->engine) { JSList * paramlist; if (!jackctl_create_param_list(driver_ptr->parameters, ¶mlist)) return false; bool ret = (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, paramlist) == 0); jackctl_destroy_param_list(paramlist); return ret; } else { return false; } } 1.9.12~dfsg/common/JackMidiPort.cpp0000644000000000000000000001214713214314510015661 0ustar rootroot/* Copyright (C) 2007 Dmitry Baikov Original JACK MIDI implementation Copyright (C) 2004 Ian Esten This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackError.h" #include "JackPortType.h" #include "JackMidiPort.h" #include #include namespace Jack { SERVER_EXPORT void JackMidiBuffer::Reset(jack_nframes_t nframes) { /* This line ate 1 hour of my life... dsbaikov */ this->nframes = nframes; write_pos = 0; event_count = 0; lost_events = 0; } SERVER_EXPORT jack_shmsize_t JackMidiBuffer::MaxEventSize() const { assert (((jack_shmsize_t) - 1) < 0); // jack_shmsize_t should be signed jack_shmsize_t left = buffer_size - (sizeof(JackMidiBuffer) + sizeof(JackMidiEvent) * (event_count + 1) + write_pos); if (left < 0) { return 0; } if (left <= JackMidiEvent::INLINE_SIZE_MAX) { return JackMidiEvent::INLINE_SIZE_MAX; } return left; } SERVER_EXPORT jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time, jack_shmsize_t size) { jack_shmsize_t space = MaxEventSize(); if (space == 0 || size > space) { jack_error("JackMidiBuffer::ReserveEvent - the buffer does not have " "enough room to enqueue a %lu byte event", size); lost_events++; return 0; } JackMidiEvent* event = &events[event_count++]; event->time = time; event->size = size; if (size <= JackMidiEvent::INLINE_SIZE_MAX) { return event->data; } write_pos += size; event->offset = buffer_size - write_pos; return (jack_midi_data_t*)this + event->offset; } void MidiBufferInit(void* buffer, size_t buffer_size, jack_nframes_t nframes) { JackMidiBuffer* midi = (JackMidiBuffer*)buffer; midi->magic = JackMidiBuffer::MAGIC; /* Since port buffer has actually always BUFFER_SIZE_MAX frames, we can safely use all the size */ midi->buffer_size = BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t); midi->Reset(nframes); } /* * The mixdown function below, is a simplest (read slowest) implementation possible. * But, since it is unlikely that it will mix many buffers with many events, * it should perform quite good. * More efficient (and possibly, fastest possible) implementation (it exists), * using calendar queue algorithm is about 3 times bigger, and uses alloca(). * So, let's listen to D.Knuth about premature optimisation, a leave the current * implementation as is, until it is proved to be a bottleneck. * Dmitry Baikov. */ static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes) { JackMidiBuffer* mix = static_cast(mixbuffer); if (!mix->IsValid()) { jack_error("Jack::MidiBufferMixdown - invalid mix buffer"); return; } mix->Reset(nframes); uint32_t mix_index[src_count]; int event_count = 0; for (int i = 0; i < src_count; ++i) { JackMidiBuffer* buf = static_cast(src_buffers[i]); if (!buf->IsValid()) { jack_error("Jack::MidiBufferMixdown - invalid source buffer"); return; } mix_index[i] = 0; event_count += buf->event_count; mix->lost_events += buf->lost_events; } int events_done; for (events_done = 0; events_done < event_count; ++events_done) { JackMidiBuffer* next_buf = 0; JackMidiEvent* next_event = 0; uint32_t next_buf_index = 0; // find the earliest event for (int i = 0; i < src_count; ++i) { JackMidiBuffer* buf = static_cast(src_buffers[i]); if (mix_index[i] >= buf->event_count) continue; JackMidiEvent* e = &buf->events[mix_index[i]]; if (!next_event || e->time < next_event->time) { next_event = e; next_buf = buf; next_buf_index = i; } } assert(next_event != 0); // write the event jack_midi_data_t* dest = mix->ReserveEvent(next_event->time, next_event->size); if (!dest) break; memcpy(dest, next_event->GetData(next_buf), next_event->size); mix_index[next_buf_index]++; } mix->lost_events += event_count - events_done; } static size_t MidiBufferSize() { return BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t); } const JackPortType gMidiPortType = { JACK_DEFAULT_MIDI_TYPE, MidiBufferSize, MidiBufferInit, MidiBufferMixdown }; } // namespace Jack 1.9.12~dfsg/common/JackMidiRawOutputWriteQueue.cpp0000644000000000000000000001172313214314510020726 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "JackError.h" #include "JackMidiRawOutputWriteQueue.h" #include "JackMidiUtil.h" using Jack::JackMidiRawOutputWriteQueue; #define STILL_TIME(c, b) ((! (b)) || ((c) < (b))) JackMidiRawOutputWriteQueue:: JackMidiRawOutputWriteQueue(JackMidiSendQueue *send_queue, size_t non_rt_size, size_t max_non_rt_messages, size_t max_rt_messages) { non_rt_queue = new JackMidiAsyncQueue(non_rt_size, max_non_rt_messages); std::auto_ptr non_rt_ptr(non_rt_queue); rt_queue = new JackMidiAsyncQueue(max_rt_messages, max_rt_messages); std::auto_ptr rt_ptr(rt_queue); non_rt_event = 0; rt_event = 0; running_status = 0; this->send_queue = send_queue; rt_ptr.release(); non_rt_ptr.release(); } JackMidiRawOutputWriteQueue::~JackMidiRawOutputWriteQueue() { delete non_rt_queue; delete rt_queue; } void JackMidiRawOutputWriteQueue::DequeueNonRealtimeEvent() { non_rt_event = non_rt_queue->DequeueEvent(); if (non_rt_event) { non_rt_event_time = non_rt_event->time; running_status = ApplyRunningStatus(non_rt_event, running_status); } } void JackMidiRawOutputWriteQueue::DequeueRealtimeEvent() { rt_event = rt_queue->DequeueEvent(); if (rt_event) { rt_event_time = rt_event->time; } } Jack::JackMidiWriteQueue::EnqueueResult JackMidiRawOutputWriteQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) { JackMidiAsyncQueue *queue = (size == 1) && (*buffer >= 0xf8) ? rt_queue : non_rt_queue; return queue->EnqueueEvent(time, size, buffer); } void JackMidiRawOutputWriteQueue::HandleWriteQueueBug(jack_nframes_t time, jack_midi_data_t byte) { jack_error("JackMidiRawOutputWriteQueue::HandleWriteQueueBug - **BUG** " "The write queue told us that it couldn't enqueue a 1-byte " "MIDI event scheduled for frame '%d'. This is probably a bug " "in the write queue implementation.", time); } jack_nframes_t JackMidiRawOutputWriteQueue::Process(jack_nframes_t boundary_frame) { if (! non_rt_event) { DequeueNonRealtimeEvent(); } if (! rt_event) { DequeueRealtimeEvent(); } while (rt_event) { jack_nframes_t current_frame = send_queue->GetNextScheduleFrame(); if ((rt_event_time > current_frame) && non_rt_event && (non_rt_event_time < rt_event_time)) { if (! SendNonRTBytes(rt_event_time < boundary_frame ? rt_event_time : boundary_frame)) { return non_rt_event_time; } current_frame = send_queue->GetNextScheduleFrame(); } if (! STILL_TIME(current_frame, boundary_frame)) { return (! non_rt_event) ? rt_event_time : non_rt_event_time < rt_event_time ? non_rt_event_time : rt_event_time; } if (! SendByte(rt_event_time, *(rt_event->buffer))) { return rt_event_time; } DequeueRealtimeEvent(); } SendNonRTBytes(boundary_frame); return non_rt_event ? non_rt_event_time : 0; } bool JackMidiRawOutputWriteQueue::SendByte(jack_nframes_t time, jack_midi_data_t byte) { switch (send_queue->EnqueueEvent(time, 1, &byte)) { case BUFFER_TOO_SMALL: HandleWriteQueueBug(time, byte); case OK: return true; default: // This is here to stop compilers from warning us about not handling // enumeration values. ; } return false; } bool JackMidiRawOutputWriteQueue::SendNonRTBytes(jack_nframes_t boundary_frame) { while (non_rt_event) { for (; non_rt_event->size; (non_rt_event->size)--, (non_rt_event->buffer)++) { jack_nframes_t current_frame = send_queue->GetNextScheduleFrame(); if (! STILL_TIME(current_frame, boundary_frame)) { return true; } if (! SendByte(non_rt_event_time, *(non_rt_event->buffer))) { return false; } } DequeueNonRealtimeEvent(); } return true; } 1.9.12~dfsg/common/JackMidiBufferWriteQueue.cpp0000644000000000000000000000411313214314510020160 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMidiBufferWriteQueue.h" #include "JackMidiUtil.h" #include "JackError.h" using Jack::JackMidiBufferWriteQueue; JackMidiBufferWriteQueue::JackMidiBufferWriteQueue() { // Empty } Jack::JackMidiWriteQueue::EnqueueResult JackMidiBufferWriteQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *data) { if (time >= next_frame_time) { return EVENT_EARLY; } if (time < last_frame_time) { time = last_frame_time; } jack_midi_data_t *dst = buffer->ReserveEvent(time - last_frame_time, size); if (! dst) { return size > max_bytes ? BUFFER_TOO_SMALL : BUFFER_FULL; } memcpy(dst, data, size); return OK; } void JackMidiBufferWriteQueue::ResetMidiBuffer(JackMidiBuffer *buffer, jack_nframes_t frames) { if (! buffer) { jack_error("JackMidiBufferWriteQueue::ResetMidiBuffer - buffer reset " "to NULL"); } else if (! buffer->IsValid()) { jack_error("JackMidiBufferWriteQueue::ResetMidiBuffer - buffer reset " "to invalid buffer"); } else { this->buffer = buffer; buffer->Reset(frames); last_frame_time = GetLastFrame(); max_bytes = buffer->MaxEventSize(); next_frame_time = last_frame_time + frames; } } 1.9.12~dfsg/common/JackAudioDriver.h0000644000000000000000000000666113214314510016020 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackAudioDriver__ #define __JackAudioDriver__ #include "JackDriver.h" namespace Jack { /*! \brief The base class for audio drivers: drivers with audio ports. A concrete derived class will have to be defined with a real audio driver API, either callback based one (like CoreAudio, PortAudio..) ones or blocking ones (like ALSA). Most of the generic audio handing code is part of this class : - concrete callback basedd derived subclasses typically have to Open/Close the underlying audio API, setup the audio callback and implement the Read/Write methods - concrete blocking based derived subclasses typically have to Open/Close the underlying audio API, implement the Read/Write methods and "wraps" the driver with the JackThreadDriver class. */ class SERVER_EXPORT JackAudioDriver : public JackDriver { protected: jack_default_audio_sample_t* GetInputBuffer(int port_index); jack_default_audio_sample_t* GetOutputBuffer(int port_index); jack_default_audio_sample_t* GetMonitorBuffer(int port_index); void HandleLatencyCallback(int status); virtual void UpdateLatencies(); int ProcessAsync(); void ProcessGraphAsync(); void ProcessGraphAsyncMaster(); void ProcessGraphAsyncSlave(); int ProcessSync(); void ProcessGraphSync(); void ProcessGraphSyncMaster(); void ProcessGraphSyncSlave(); public: JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); virtual ~JackAudioDriver(); virtual int Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); /* To be called by the underlying driver audio callback, or possibly by a RT thread (using JackThreadedDriver decorator) when a blocking read/write underlying API is used (like ALSA) */ virtual int Process(); virtual int Attach(); virtual int Detach(); virtual int Write(); virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetSampleRate(jack_nframes_t sample_rate); virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); }; } // end of namespace #endif 1.9.12~dfsg/common/JackConnectionManager.cpp0000644000000000000000000003147213214314510017526 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackConnectionManager.h" #include "JackClientControl.h" #include "JackEngineControl.h" #include "JackGlobals.h" #include "JackError.h" #include #include #include namespace Jack { JackConnectionManager::JackConnectionManager() { int i; jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager)); for (i = 0; i < PORT_NUM_MAX; i++) { fConnection[i].Init(); } fLoopFeedback.Init(); jack_log("JackConnectionManager::InitClients"); for (i = 0; i < CLIENT_NUM; i++) { InitRefNum(i); } } JackConnectionManager::~JackConnectionManager() {} //-------------- // Internal API //-------------- bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const { jack_log("JackConnectionManager::IsLoopPathAux ref1 = %ld ref2 = %ld", ref1, ref2); if (ref1 < GetEngineControl()->fDriverNum || ref2 < GetEngineControl()->fDriverNum) { return false; } else if (ref1 == ref2) { // Same refnum return true; } else { jack_int_t output[CLIENT_NUM]; fConnectionRef.GetOutputTable(ref1, output); if (fConnectionRef.IsInsideTable(ref2, output)) { // If ref2 is contained in the outputs of ref1 return true; } else { for (int i = 0; i < CLIENT_NUM && output[i] != EMPTY; i++) { // Otherwise recurse for all ref1 outputs if (IsLoopPathAux(output[i], ref2)) { return true; // Stop when a path is found } } return false; } } } //-------------- // External API //-------------- /*! \brief Connect port_src to port_dst. */ int JackConnectionManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst) { jack_log("JackConnectionManager::Connect port_src = %ld port_dst = %ld", port_src, port_dst); if (fConnection[port_src].AddItem(port_dst)) { return 0; } else { jack_error("Connection table is full !!"); return -1; } } /*! \brief Disconnect port_src from port_dst. */ int JackConnectionManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst) { jack_log("JackConnectionManager::Disconnect port_src = %ld port_dst = %ld", port_src, port_dst); if (fConnection[port_src].RemoveItem(port_dst)) { return 0; } else { jack_error("Connection not found !!"); return -1; } } /*! \brief Check if port_src and port_dst are connected. */ bool JackConnectionManager::IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const { return fConnection[port_src].CheckItem(port_dst); } /*! \brief Get the connection port array. */ const jack_int_t* JackConnectionManager::GetConnections(jack_port_id_t port_index) const { return fConnection[port_index].GetItems(); } //------------------------ // Client port management //------------------------ /*! \brief Add an input port to a client. */ int JackConnectionManager::AddInputPort(int refnum, jack_port_id_t port_index) { if (fInputPort[refnum].AddItem(port_index)) { jack_log("JackConnectionManager::AddInputPort ref = %ld port = %ld", refnum, port_index); return 0; } else { jack_error("Maximum number of input ports is reached for application ref = %ld", refnum); return -1; } } /*! \brief Add an output port to a client. */ int JackConnectionManager::AddOutputPort(int refnum, jack_port_id_t port_index) { if (fOutputPort[refnum].AddItem(port_index)) { jack_log("JackConnectionManager::AddOutputPort ref = %ld port = %ld", refnum, port_index); return 0; } else { jack_error("Maximum number of output ports is reached for application ref = %ld", refnum); return -1; } } /*! \brief Remove an input port from a client. */ int JackConnectionManager::RemoveInputPort(int refnum, jack_port_id_t port_index) { jack_log("JackConnectionManager::RemoveInputPort ref = %ld port_index = %ld ", refnum, port_index); if (fInputPort[refnum].RemoveItem(port_index)) { return 0; } else { jack_error("Input port index = %ld not found for application ref = %ld", port_index, refnum); return -1; } } /*! \brief Remove an output port from a client. */ int JackConnectionManager::RemoveOutputPort(int refnum, jack_port_id_t port_index) { jack_log("JackConnectionManager::RemoveOutputPort ref = %ld port_index = %ld ", refnum, port_index); if (fOutputPort[refnum].RemoveItem(port_index)) { return 0; } else { jack_error("Output port index = %ld not found for application ref = %ld", port_index, refnum); return -1; } } /*! \brief Get the input port array of a given refnum. */ const jack_int_t* JackConnectionManager::GetInputPorts(int refnum) { return fInputPort[refnum].GetItems(); } /*! \brief Get the output port array of a given refnum. */ const jack_int_t* JackConnectionManager::GetOutputPorts(int refnum) { return fOutputPort[refnum].GetItems(); } /*! \brief Init the refnum. */ void JackConnectionManager::InitRefNum(int refnum) { fInputPort[refnum].Init(); fOutputPort[refnum].Init(); fConnectionRef.Init(refnum); fInputCounter[refnum].SetValue(0); } /*! \brief Reset all clients activation. */ void JackConnectionManager::ResetGraph(JackClientTiming* timing) { // Reset activation counter : must be done *before* starting to resume clients for (int i = 0; i < CLIENT_NUM; i++) { fInputCounter[i].Reset(); timing[i].fStatus = NotTriggered; } } /*! \brief Wait on the input synchro. */ int JackConnectionManager::SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec) { bool res; if ((res = table[control->fRefNum].TimedWait(time_out_usec))) { timing[control->fRefNum].fStatus = Running; timing[control->fRefNum].fAwakeAt = GetMicroSeconds(); } return (res) ? 0 : -1; } /*! \brief Signal clients connected to the given client. */ int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing) { jack_time_t current_date = GetMicroSeconds(); const jack_int_t* output_ref = fConnectionRef.GetItems(control->fRefNum); int res = 0; // Update state and timestamp of current client timing[control->fRefNum].fStatus = Finished; timing[control->fRefNum].fFinishedAt = current_date; for (int i = 0; i < CLIENT_NUM; i++) { // Signal connected clients or drivers if (output_ref[i] > 0) { // Update state and timestamp of destination clients timing[i].fStatus = Triggered; timing[i].fSignaledAt = current_date; if (!fInputCounter[i].Signal(table + i, control)) { jack_log("JackConnectionManager::ResumeRefNum error: ref = %ld output = %ld ", control->fRefNum, i); res = -1; } } } return res; } static bool HasNoConnection(jack_int_t* table) { for (int ref = 0; ref < CLIENT_NUM; ref++) { if (table[ref] > 0) return false; } return true; } // Using http://en.wikipedia.org/wiki/Topological_sorting void JackConnectionManager::TopologicalSort(std::vector& sorted) { JackFixedMatrix* tmp = new JackFixedMatrix; std::set level; fConnectionRef.Copy(*tmp); // Inputs of the graph level.insert(AUDIO_DRIVER_REFNUM); level.insert(FREEWHEEL_DRIVER_REFNUM); while (level.size() > 0) { jack_int_t refnum = *level.begin(); sorted.push_back(refnum); level.erase(level.begin()); const jack_int_t* output_ref1 = tmp->GetItems(refnum); for (int dst = 0; dst < CLIENT_NUM; dst++) { if (output_ref1[dst] > 0) { tmp->ClearItem(refnum, dst); jack_int_t output_ref2[CLIENT_NUM]; tmp->GetOutputTable1(dst, output_ref2); if (HasNoConnection(output_ref2)) { level.insert(dst); } } } } delete tmp; } /*! \brief Increment the number of ports between 2 clients, if the 2 clients become connected, then the Activation counter is updated. */ void JackConnectionManager::IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst) { int ref1 = GetOutputRefNum(port_src); int ref2 = GetInputRefNum(port_dst); assert(ref1 >= 0 && ref2 >= 0); DirectConnect(ref1, ref2); jack_log("JackConnectionManager::IncConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2); } /*! \brief Decrement the number of ports between 2 clients, if the 2 clients become disconnected, then the Activation counter is updated. */ void JackConnectionManager::DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst) { int ref1 = GetOutputRefNum(port_src); int ref2 = GetInputRefNum(port_dst); assert(ref1 >= 0 && ref2 >= 0); DirectDisconnect(ref1, ref2); jack_log("JackConnectionManager::DecConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2); } /*! \brief Directly connect 2 reference numbers. */ void JackConnectionManager::DirectConnect(int ref1, int ref2) { assert(ref1 >= 0 && ref2 >= 0); if (fConnectionRef.IncItem(ref1, ref2) == 1) { // First connection between client ref1 and client ref2 jack_log("JackConnectionManager::DirectConnect first: ref1 = %ld ref2 = %ld", ref1, ref2); fInputCounter[ref2].IncValue(); } } /*! \brief Directly disconnect 2 reference numbers. */ void JackConnectionManager::DirectDisconnect(int ref1, int ref2) { assert(ref1 >= 0 && ref2 >= 0); if (fConnectionRef.DecItem(ref1, ref2) == 0) { // Last connection between client ref1 and client ref2 jack_log("JackConnectionManager::DirectDisconnect last: ref1 = %ld ref2 = %ld", ref1, ref2); fInputCounter[ref2].DecValue(); } } /*! \brief Returns the connections state between 2 refnum. */ bool JackConnectionManager::IsDirectConnection(int ref1, int ref2) const { assert(ref1 >= 0 && ref2 >= 0); return (fConnectionRef.GetItemCount(ref1, ref2) > 0); } /*! \brief Get the client refnum of a given input port. */ int JackConnectionManager::GetInputRefNum(jack_port_id_t port_index) const { for (int i = 0; i < CLIENT_NUM; i++) { if (fInputPort[i].CheckItem(port_index)) { return i; } } return -1; } /*! \brief Get the client refnum of a given ouput port. */ int JackConnectionManager::GetOutputRefNum(jack_port_id_t port_index) const { for (int i = 0; i < CLIENT_NUM; i++) { if (fOutputPort[i].CheckItem(port_index)) { return i; } } return -1; } /*! \brief Test is a connection path exists between port_src and port_dst. */ bool JackConnectionManager::IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const { return IsLoopPathAux(GetInputRefNum(port_dst), GetOutputRefNum(port_src)); } bool JackConnectionManager::IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const { return (fLoopFeedback.GetConnectionIndex(GetOutputRefNum(port_src), GetInputRefNum(port_dst)) >= 0); } bool JackConnectionManager::IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) { int ref1 = GetOutputRefNum(port_src); int ref2 = GetInputRefNum(port_dst); // Add an activation connection in the other direction jack_log("JackConnectionManager::IncFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2); assert(ref1 >= 0 && ref2 >= 0); if (ref1 != ref2) { DirectConnect(ref2, ref1); } return fLoopFeedback.IncConnection(ref1, ref2); // Add the feedback connection } bool JackConnectionManager::DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) { int ref1 = GetOutputRefNum(port_src); int ref2 = GetInputRefNum(port_dst); // Remove an activation connection in the other direction jack_log("JackConnectionManager::DecFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2); assert(ref1 >= 0 && ref2 >= 0); if (ref1 != ref2) { DirectDisconnect(ref2, ref1); } return fLoopFeedback.DecConnection(ref1, ref2); // Remove the feedback connection } } // end of namespace 1.9.12~dfsg/common/JackExternalClient.h0000644000000000000000000000312113214314510016510 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackExternalClient__ #define __JackExternalClient__ #include "JackClientInterface.h" #include "JackPlatformPlug.h" namespace Jack { struct JackClientControl; /*! \brief Server side implementation of library clients. */ class JackExternalClient : public JackClientInterface { private: JackNotifyChannel fChannel; /*! Server/client communication channel */ JackClientControl* fClientControl; /*! Client control in shared memory */ public: JackExternalClient(); virtual ~JackExternalClient(); int Open(const char* name, int pid, int refnum, int uuid, int* shared_client); int Close(); int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); JackClientControl* GetClientControl() const; }; } // end of namespace #endif 1.9.12~dfsg/common/JackEngine.h0000644000000000000000000001416313214314510015004 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackEngine__ #define __JackEngine__ #include "JackConstants.h" #include "JackGraphManager.h" #include "JackSynchro.h" #include "JackMutex.h" #include "JackTransportEngine.h" #include "JackPlatformPlug.h" #include "JackRequest.h" #include "JackChannel.h" #include namespace Jack { class JackClientInterface; struct JackEngineControl; class JackExternalClient; /*! \brief Engine description. */ class SERVER_EXPORT JackEngine : public JackLockAble { friend class JackLockedEngine; private: JackGraphManager* fGraphManager; JackEngineControl* fEngineControl; char fSelfConnectMode; JackClientInterface* fClientTable[CLIENT_NUM]; JackSynchro* fSynchroTable; JackServerNotifyChannel fChannel; /*! To communicate between the RT thread and server */ JackProcessSync fSignal; jack_time_t fLastSwitchUsecs; int fSessionPendingReplies; detail::JackChannelTransactionInterface* fSessionTransaction; JackSessionNotifyResult* fSessionResult; std::map fReservationMap; int fMaxUUID; int ClientCloseAux(int refnum, bool wait); void CheckXRun(jack_time_t callback_usecs); int NotifyAddClient(JackClientInterface* new_client, const char* new_name, int refnum); void NotifyRemoveClient(const char* name, int refnum); void ProcessNext(jack_time_t callback_usecs); void ProcessCurrent(jack_time_t callback_usecs); bool ClientCheckName(const char* name); bool GenerateUniqueName(char* name); int AllocateRefnum(); void ReleaseRefnum(int refnum); int ClientNotify(JackClientInterface* client, int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); void NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2); void NotifyClients(int event, int sync, const char* message, int value1, int value2); void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); void NotifyPortRename(jack_port_id_t src, const char* old_name); void NotifyActivate(int refnum); int GetNewUUID(); void EnsureUUID(int uuid); bool CheckClient(int refnum) { return (refnum >= 0 && refnum < CLIENT_NUM && fClientTable[refnum] != NULL); } int CheckPortsConnect(int refnum, jack_port_id_t src, jack_port_id_t dst); public: JackEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler, char self_connect_mode); ~JackEngine(); int Open(); int Close(); // Client management int ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status); int ClientExternalOpen(const char* name, int pid, int uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait); int ClientExternalClose(int refnum); int ClientInternalClose(int refnum, bool wait); int ClientActivate(int refnum, bool is_real_time); int ClientDeactivate(int refnum); void ClientKill(int refnum); int GetClientPID(const char* name); int GetClientRefNum(const char* name); // Internal client management int GetInternalClientName(int int_ref, char* name_res); int InternalClientHandle(const char* client_name, int* status, int* int_ref); int InternalClientUnload(int refnum, int* status); // Port management int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port); int PortUnRegister(int refnum, jack_port_id_t port); int PortConnect(int refnum, const char* src, const char* dst); int PortDisconnect(int refnum, const char* src, const char* dst); int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst); int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst); int PortRename(int refnum, jack_port_id_t port, const char* name); int ComputeTotalLatencies(); // Graph bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); // Notifications void NotifyDriverXRun(); void NotifyClientXRun(int refnum); void NotifyFailure(int code, const char* reason); void NotifyGraphReorder(); void NotifyBufferSize(jack_nframes_t buffer_size); void NotifySampleRate(jack_nframes_t sample_rate); void NotifyFreewheel(bool onoff); void NotifyQuit(); // Session management void SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, detail::JackChannelTransactionInterface *socket, JackSessionNotifyResult** result); int SessionReply(int refnum); int GetUUIDForClientName(const char *client_name, char *uuid_res); int GetClientNameForUUID(const char *uuid, char *name_res); int ReserveClientName(const char *name, const char *uuid); int ClientHasSessionCallback(const char *name); }; } // end of namespace #endif 1.9.12~dfsg/common/JackDebugClient.cpp0000644000000000000000000005523613214314510016325 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackDebugClient.h" #include "JackEngineControl.h" #include "JackException.h" #include "JackError.h" #include "JackTime.h" #include #include #include #include #include #include using namespace std; namespace Jack { JackDebugClient::JackDebugClient(JackClient * client) : JackClient(client->fSynchroTable) { fTotalPortNumber = 1; // The total number of port opened and maybe closed. Historical view. fOpenPortNumber = 0; // The current number of opened port. fIsActivated = 0; fIsDeactivated = 0; fIsClosed = 0; fClient = client; fFreewheel = false; } JackDebugClient::~JackDebugClient() { fTotalPortNumber--; // fTotalPortNumber start at 1 *fStream << endl << endl << "----------------------------------- JackDebugClient summary ------------------------------- " << endl << endl; *fStream << "Client flags ( 1:yes / 0:no ) :" << endl; *fStream << setw(5) << "- Client call activated : " << fIsActivated << endl; *fStream << setw(5) << "- Client call deactivated : " << fIsDeactivated << endl; *fStream << setw(5) << "- Client call closed : " << fIsClosed << endl; *fStream << setw(5) << "- Total number of instantiated port : " << fTotalPortNumber << endl; *fStream << setw(5) << "- Number of port remaining open when exiting client : " << fOpenPortNumber << endl; if (fOpenPortNumber != 0) *fStream << "!!! WARNING !!! Some ports have not been unregistered ! Incorrect exiting !" << endl; if (fIsDeactivated != fIsActivated) *fStream << "!!! ERROR !!! Client seem to not perform symmetric activation-deactivation ! (not the same number of activate and deactivate)" << endl; if (fIsClosed == 0) *fStream << "!!! ERROR !!! Client have not been closed with jack_client_close() !" << endl; *fStream << endl << endl << "---------------------------- JackDebugClient detailed port summary ------------------------ " << endl << endl; //for (int i = 0; i < fTotalPortNumber ; i++) { for (int i = 1; i <= fTotalPortNumber ; i++) { *fStream << endl << "Port index (internal debug test value) : " << i << endl; *fStream << setw(5) << "- Name : " << fPortList[i].name << endl; *fStream << setw(5) << "- idport : " << fPortList[i].idport << endl; *fStream << setw(5) << "- IsConnected : " << fPortList[i].IsConnected << endl; *fStream << setw(5) << "- IsUnregistered : " << fPortList[i].IsUnregistered << endl; if (fPortList[i].IsUnregistered == 0) *fStream << "!!! WARNING !!! Port have not been unregistered ! Incorrect exiting !" << endl; } *fStream << "delete object JackDebugClient : end of tracing" << endl; delete fStream; delete fClient; } int JackDebugClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int res = fClient->Open(server_name, name, uuid, options, status); char provstr[256]; char buffer[256]; time_t curtime; struct tm *loctime; /* Get the current time. */ curtime = time (NULL); /* Convert it to local time representation. */ loctime = localtime (&curtime); strftime (buffer, 256, "%I-%M", loctime); snprintf(provstr, sizeof(provstr), "JackClientDebug-%s-%s.log", name, buffer); fStream = new ofstream(provstr, ios_base::ate); if (fStream->is_open()) { if (res == -1) { *fStream << "Trying to open client with name '" << name << "' with bad result (client not opened)." << res << endl; } else { *fStream << "Open client with name '" << name << "'." << endl; } } else { jack_log("JackDebugClient::Open : cannot open log file"); } strcpy(fClientName, name); return res; } int JackDebugClient::Close() { *fStream << "Client '" << fClientName << "' was closed" << endl; int res = fClient->Close(); fIsClosed++; return res; } void JackDebugClient::CheckClient(const char* function_name) const { #ifdef WIN32 *fStream << "CheckClient : " << function_name << ", calling thread : " << GetCurrentThread() << endl; #else *fStream << "CheckClient : " << function_name << ", calling thread : " << pthread_self() << endl; #endif if (fIsClosed > 0) { *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed " << "from " << function_name << endl; *fStream << "This is likely to cause crash !'" << endl; #ifdef __APPLE__ // Debugger(); #endif } } jack_native_thread_t JackDebugClient::GetThreadID() { CheckClient("GetThreadID"); return fClient->GetThreadID(); } JackGraphManager* JackDebugClient::GetGraphManager() const { CheckClient("GetGraphManager"); return fClient->GetGraphManager(); } JackEngineControl* JackDebugClient::GetEngineControl() const { CheckClient("GetEngineControl"); return fClient->GetEngineControl(); } /*! \brief Notification received from the server. */ int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { CheckClient("ClientNotify"); return fClient->ClientNotify( refnum, name, notify, sync, message, value1, value2); } int JackDebugClient::Activate() { CheckClient("Activate"); int res = fClient->Activate(); fIsActivated++; if (fIsDeactivated) *fStream << "Client '" << fClientName << "' call activate a new time (it already call 'activate' previously)." << endl; *fStream << "Client '" << fClientName << "' Activated" << endl; if (res != 0) *fStream << "Client '" << fClientName << "' try to activate but server return " << res << " ." << endl; return res; } int JackDebugClient::Deactivate() { CheckClient("Deactivate"); int res = fClient->Deactivate(); fIsDeactivated++; if (fIsActivated == 0) *fStream << "Client '" << fClientName << "' deactivate while it hasn't been previoulsy activated !" << endl; *fStream << "Client '" << fClientName << "' Deactivated" << endl; if (res != 0) *fStream << "Client '" << fClientName << "' try to deactivate but server return " << res << " ." << endl; return res; } //----------------- // Port management //----------------- int JackDebugClient::PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size) { CheckClient("PortRegister"); int res = fClient->PortRegister(port_name, port_type, flags, buffer_size); if (res <= 0) { *fStream << "Client '" << fClientName << "' try port register ('" << port_name << "') and server return error " << res << " ." << endl; } else { if (fTotalPortNumber < MAX_PORT_HISTORY) { fPortList[fTotalPortNumber].idport = res; strcpy(fPortList[fTotalPortNumber].name, port_name); fPortList[fTotalPortNumber].IsConnected = 0; fPortList[fTotalPortNumber].IsUnregistered = 0; } else { *fStream << "!!! WARNING !!! History is full : no more port history will be recorded." << endl; } fTotalPortNumber++; fOpenPortNumber++; *fStream << "Client '" << fClientName << "' port register with portname '" << port_name << " port " << res << "' ." << endl; } return res; } int JackDebugClient::PortUnRegister(jack_port_id_t port_index) { CheckClient("PortUnRegister"); int res = fClient->PortUnRegister(port_index); fOpenPortNumber--; int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (fPortList[i].idport == port_index) { // We found the last record if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : '" << fClientName << "' id deregistering port '" << fPortList[i].name << "' that have already been unregistered !" << endl; fPortList[i].IsUnregistered++; break; } } if (i == 0) // Port is not found *fStream << "JackClientDebug : PortUnregister : port " << port_index << " was not previously registered !" << endl; if (res != 0) *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << res << endl; *fStream << "Client '" << fClientName << "' unregister port '" << port_index << "'." << endl; return res; } int JackDebugClient::PortConnect(const char* src, const char* dst) { CheckClient("PortConnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! Trying to connect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl; int i; int res = fClient->PortConnect( src, dst); for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (strcmp(fPortList[i].name, src) == 0) { // We found the last record in sources if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! Connecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected++; *fStream << "Connecting port " << src << " to " << dst << ". "; break; } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! Connecting port " << dst << " previoulsy unregistered !" << endl; fPortList[i].IsConnected++; *fStream << "Connecting port " << src << " to " << dst << ". "; break; } } if (i == 0) // Port is not found *fStream << "JackClientDebug : PortConnect : port was not found in debug database !" << endl; if (res != 0) *fStream << "Client '" << fClientName << "' try to do PortConnect but server return " << res << " ." << endl; //*fStream << "Client Port Connect done with names" << endl; return res; } int JackDebugClient::PortDisconnect(const char* src, const char* dst) { CheckClient("PortDisconnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! Trying to disconnect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl; int res = fClient->PortDisconnect( src, dst); int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (strcmp(fPortList[i].name, src) == 0) { // We found the record in sources if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "disconnecting port " << src << ". "; break; } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disonnecting port " << dst << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "disconnecting port " << dst << ". "; break; } } if (i == 0) // Port is not found *fStream << "JackClientDebug : PortDisConnect : port was not found in debug database !" << endl; if (res != 0) *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << res << " ." << endl; //*fStream << "Client Port Disconnect done." << endl; return res; } int JackDebugClient::PortDisconnect(jack_port_id_t src) { CheckClient("PortDisconnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! : Trying to disconnect port " << src << " while that client has not been activated !" << endl; int res = fClient->PortDisconnect(src); int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (fPortList[i].idport == src) { // We found the record in sources if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "Disconnecting port " << src << ". " << endl; break; } } if (i == 0) // Port is not found *fStream << "JackClientDebug : PortDisconnect : port was not found in debug database !" << endl; if (res != 0) *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << res << " ." << endl; //*fStream << "Client Port Disconnect with ID done." << endl; return res; } int JackDebugClient::PortIsMine(jack_port_id_t port_index) { CheckClient("PortIsMine"); *fStream << "JackClientDebug : PortIsMine port_index " << port_index << endl; return fClient->PortIsMine(port_index); } int JackDebugClient::PortRename(jack_port_id_t port_index, const char* name) { CheckClient("PortRename"); *fStream << "JackClientDebug : PortRename port_index " << port_index << "name" << name << endl; return fClient->PortRename(port_index, name); } //-------------------- // Context management //-------------------- int JackDebugClient::SetBufferSize(jack_nframes_t buffer_size) { CheckClient("SetBufferSize"); *fStream << "JackClientDebug : SetBufferSize buffer_size " << buffer_size << endl; return fClient->SetBufferSize(buffer_size); } int JackDebugClient::SetFreeWheel(int onoff) { CheckClient("SetFreeWheel"); if (onoff && fFreewheel) *fStream << "!!! ERROR !!! : Freewheel setup seems incorrect : set = ON while FW is already ON " << endl; if (!onoff && !fFreewheel) *fStream << "!!! ERROR !!! : Freewheel setup seems incorrect : set = OFF while FW is already OFF " << endl; fFreewheel = onoff ? true : false; return fClient->SetFreeWheel(onoff); } int JackDebugClient::ComputeTotalLatencies() { CheckClient("ComputeTotalLatencies"); return fClient->ComputeTotalLatencies(); } /* ShutDown is called: - from the RT thread when Execute method fails - possibly from a "closed" notification channel (Not needed since the synch object used (Sema of Fifo will fails when server quits... see ShutDown)) */ void JackDebugClient::ShutDown(jack_status_t code, const char* message) { CheckClient("ShutDown"); fClient->ShutDown(code, message); } //--------------------- // Transport management //--------------------- int JackDebugClient::ReleaseTimebase() { CheckClient("ReleaseTimebase"); return fClient->ReleaseTimebase(); } int JackDebugClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg) { CheckClient("SetSyncCallback"); return fClient->SetSyncCallback(sync_callback, arg); } int JackDebugClient::SetSyncTimeout(jack_time_t timeout) { CheckClient("SetSyncTimeout"); *fStream << "JackClientDebug : SetSyncTimeout timeout " << timeout << endl; return fClient->SetSyncTimeout(timeout); } int JackDebugClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg) { CheckClient("SetTimebaseCallback"); return fClient->SetTimebaseCallback( conditional, timebase_callback, arg); } void JackDebugClient::TransportLocate(jack_nframes_t frame) { CheckClient("TransportLocate"); *fStream << "JackClientDebug : TransportLocate frame " << frame << endl; fClient->TransportLocate(frame); } jack_transport_state_t JackDebugClient::TransportQuery(jack_position_t* pos) { CheckClient("TransportQuery"); return fClient->TransportQuery(pos); } jack_nframes_t JackDebugClient::GetCurrentTransportFrame() { CheckClient("GetCurrentTransportFrame"); return fClient->GetCurrentTransportFrame(); } int JackDebugClient::TransportReposition(const jack_position_t* pos) { CheckClient("TransportReposition"); return fClient->TransportReposition(pos); } void JackDebugClient::TransportStart() { CheckClient("TransportStart"); fClient->TransportStart(); } void JackDebugClient::TransportStop() { CheckClient("TransportStop"); fClient->TransportStop(); } //--------------------- // Callback management //--------------------- void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg) { CheckClient("OnShutdown"); fClient->OnShutdown(callback, arg); } void JackDebugClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) { CheckClient("OnInfoShutdown"); fClient->OnInfoShutdown(callback, arg); } int JackDebugClient::TimeCallback(jack_nframes_t nframes, void *arg) { JackDebugClient* client = (JackDebugClient*)arg; jack_time_t t1 = GetMicroSeconds(); int res = client->fProcessTimeCallback(nframes, client->fProcessTimeCallbackArg); if (res == 0) { jack_time_t t2 = GetMicroSeconds(); long delta = long((t2 - t1) - client->GetEngineControl()->fPeriodUsecs); if (delta > 0 && !client->fFreewheel) { *client->fStream << "!!! ERROR !!! : Process overload of " << delta << " us" << endl; } } return res; } int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg) { CheckClient("SetProcessCallback"); fProcessTimeCallback = callback; fProcessTimeCallbackArg = arg; if (callback == NULL) { // Clear the callback... return fClient->SetProcessCallback(callback, arg); } else { // Setup the measuring version... return fClient->SetProcessCallback(TimeCallback, this); } } int JackDebugClient::SetXRunCallback(JackXRunCallback callback, void *arg) { CheckClient("SetXRunCallback"); return fClient->SetXRunCallback(callback, arg); } int JackDebugClient::SetInitCallback(JackThreadInitCallback callback, void *arg) { CheckClient("SetInitCallback"); return fClient->SetInitCallback(callback, arg); } int JackDebugClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg) { CheckClient("SetGraphOrderCallback"); return fClient->SetGraphOrderCallback(callback, arg); } int JackDebugClient::SetBufferSizeCallback(JackBufferSizeCallback callback, void *arg) { CheckClient("SetBufferSizeCallback"); return fClient->SetBufferSizeCallback(callback, arg); } int JackDebugClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg) { CheckClient("SetClientRegistrationCallback"); return fClient->SetClientRegistrationCallback(callback, arg); } int JackDebugClient::SetFreewheelCallback(JackFreewheelCallback callback, void *arg) { CheckClient("SetFreewheelCallback"); return fClient->SetFreewheelCallback(callback, arg); } int JackDebugClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback, void *arg) { CheckClient("SetPortRegistrationCallback"); return fClient->SetPortRegistrationCallback(callback, arg); } int JackDebugClient::SetPortConnectCallback(JackPortConnectCallback callback, void *arg) { CheckClient("SetPortConnectCallback"); return fClient->SetPortConnectCallback(callback, arg); } int JackDebugClient::SetPortRenameCallback(JackPortRenameCallback callback, void *arg) { CheckClient("SetPortRenameCallback"); return fClient->SetPortRenameCallback(callback, arg); } int JackDebugClient::SetSessionCallback(JackSessionCallback callback, void *arg) { CheckClient("SetSessionCallback"); return fClient->SetSessionCallback(callback, arg); } int JackDebugClient::SetLatencyCallback(JackLatencyCallback callback, void *arg) { CheckClient("SetLatencyCallback"); return fClient->SetLatencyCallback(callback, arg); } int JackDebugClient::SetProcessThread(JackThreadCallback fun, void *arg) { CheckClient("SetProcessThread"); return fClient->SetProcessThread(fun, arg); } jack_session_command_t* JackDebugClient::SessionNotify(const char* target, jack_session_event_type_t type, const char* path) { CheckClient("SessionNotify"); *fStream << "JackClientDebug : SessionNotify target " << target << "type " << type << "path " << path << endl; return fClient->SessionNotify(target, type, path); } int JackDebugClient::SessionReply(jack_session_event_t* ev) { CheckClient("SessionReply"); return fClient->SessionReply(ev); } char* JackDebugClient::GetUUIDForClientName(const char* client_name) { CheckClient("GetUUIDForClientName"); *fStream << "JackClientDebug : GetUUIDForClientName client_name " << client_name << endl; return fClient->GetUUIDForClientName(client_name); } char* JackDebugClient::GetClientNameByUUID(const char* uuid) { CheckClient("GetClientNameByUUID"); *fStream << "JackClientDebug : GetClientNameByUUID uuid " << uuid << endl; return fClient->GetClientNameByUUID(uuid); } int JackDebugClient::ReserveClientName(const char* client_name, const char* uuid) { CheckClient("ReserveClientName"); *fStream << "JackClientDebug : ReserveClientName client_name " << client_name << "uuid " << uuid << endl; return fClient->ReserveClientName(client_name, uuid); } int JackDebugClient::ClientHasSessionCallback(const char* client_name) { CheckClient("ClientHasSessionCallback"); *fStream << "JackClientDebug : ClientHasSessionCallback client_name " << client_name << endl; return fClient->ClientHasSessionCallback(client_name); } JackClientControl* JackDebugClient::GetClientControl() const { CheckClient("GetClientControl"); return fClient->GetClientControl(); } // Internal clients char* JackDebugClient::GetInternalClientName(int ref) { CheckClient("GetInternalClientName"); return fClient->GetInternalClientName(ref); } int JackDebugClient::InternalClientHandle(const char* client_name, jack_status_t* status) { CheckClient("InternalClientHandle"); return fClient->InternalClientHandle(client_name, status); } int JackDebugClient::InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va) { CheckClient("InternalClientLoad"); return fClient->InternalClientLoad(client_name, options, status, va); } void JackDebugClient::InternalClientUnload(int ref, jack_status_t* status) { CheckClient("InternalClientUnload"); fClient->InternalClientUnload(ref, status); } } // end of namespace 1.9.12~dfsg/common/JackWeakAPI.c0000644000000000000000000005233413214314510015015 0ustar rootroot//============================================================================= // // jackWeakAPI partly based on Julien Pommier (PianoTeq : http://www.pianoteq.com/) code. // // Copyright (C) 2002-2007 Werner Schweer and others // Copyright (C) 2009 Grame // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation; either version 2.1 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // You should have received a copy of the GNU Lesser General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include #include #include #ifndef WIN32 #include #endif #include #include /* dynamically load libjack and forward all registered calls to libjack (similar to what relaytool is trying to do, but more portably..) */ typedef void (*print_function)(const char *); typedef void *(*thread_routine)(void*); static int libjack_is_present = 0; // public symbol, similar to what relaytool does. #ifdef WIN32 static HMODULE libjack_handle = 0; #else static void *libjack_handle = 0; #endif #ifndef WIN32 static void __attribute__((constructor)) tryload_libjack() #else void tryload_libjack() #endif { if (getenv("SKIP_LIBJACK") == 0) { // just in case libjack is causing troubles.. #ifdef __APPLE__ libjack_handle = dlopen("libjack.0.dylib", RTLD_LAZY); if (!libjack_handle) { fprintf(stderr, "dlopen error : %s \n", dlerror()); } libjack_handle = dlopen("/usr/local/lib/libjack.0.dylib", RTLD_LAZY); if (!libjack_handle) { fprintf(stderr, "dlopen error : %s \n", dlerror()); } #elif defined(WIN32) #ifdef _WIN64 libjack_handle = LoadLibrary("libjack64.dll"); #else libjack_handle = LoadLibrary("libjack.dll"); #endif #else libjack_handle = dlopen("libjack.so.0", RTLD_LAZY); #endif } libjack_is_present = (libjack_handle != 0); } void *load_jack_function(const char *fn_name) { void *fn = 0; if (!libjack_handle) { fprintf (stderr, "libjack not found, so do not try to load %s ffs !\n", fn_name); return 0; } #ifdef WIN32 fn = (void*)GetProcAddress(libjack_handle, fn_name); #else fn = dlsym(libjack_handle, fn_name); #endif if (!fn) { #ifdef WIN32 char* lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL ); fprintf(stderr, "could not GetProcAddress( %s ), %s \n", fn_name, lpMsgBuf); #else fprintf(stderr, "could not dlsym( %s ), %s \n", fn_name, dlerror()); #endif } return fn; } #define DECL_FUNCTION(return_type, fn_name, arguments_types, arguments) \ typedef return_type (*fn_name##_ptr_t)arguments_types; \ return_type fn_name arguments_types { \ static fn_name##_ptr_t fn = 0; \ if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ if (fn) return (*fn)arguments; \ else return (return_type)-1; \ } #define DECL_FUNCTION_NULL(return_type, fn_name, arguments_types, arguments) \ typedef return_type (*fn_name##_ptr_t)arguments_types; \ return_type fn_name arguments_types { \ static fn_name##_ptr_t fn = 0; \ if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ if (fn) return (*fn)arguments; \ else return (return_type)0; \ } #define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \ typedef void (*fn_name##_ptr_t)arguments_types; \ void fn_name arguments_types { \ static fn_name##_ptr_t fn = 0; \ if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ if (fn) (*fn)arguments; \ } DECL_VOID_FUNCTION(jack_get_version, (int *major_ptr, int *minor_ptr, int *micro_ptr, int *proto_ptr), (major_ptr, minor_ptr, micro_ptr, proto_ptr)); DECL_FUNCTION_NULL(const char *, jack_get_version_string, (), ()); DECL_FUNCTION_NULL(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), (client_name, options, status)); DECL_FUNCTION(int, jack_client_close, (jack_client_t *client), (client)); DECL_FUNCTION_NULL(jack_client_t *, jack_client_new, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_client_name_size, (), ()); DECL_FUNCTION_NULL(char*, jack_get_client_name, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, const char *load_name, const char *load_init), (client_name, load_name, load_init)); DECL_VOID_FUNCTION(jack_internal_client_close, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_is_realtime, (jack_client_t *client), (client)); DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, shutdown_callback, arg)); DECL_VOID_FUNCTION(jack_on_info_shutdown, (jack_client_t* client, JackInfoShutdownCallback shutdown_callback, void* arg), (client, shutdown_callback, arg)); DECL_FUNCTION(int, jack_set_process_callback, (jack_client_t *client, JackProcessCallback process_callback, void *arg), (client, process_callback, arg)); DECL_FUNCTION(jack_nframes_t, jack_thread_wait, (jack_client_t *client, int status), (client, status)); // DECL_FUNCTION(jack_nframes_t, jack_cycle_wait, (jack_client_t *client), (client)); DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, int status), (client, status)); DECL_FUNCTION(int, jack_set_process_thread, (jack_client_t *client, JackThreadCallback fun, void *arg), (client, fun, arg)); DECL_FUNCTION(int, jack_set_thread_init_callback, (jack_client_t *client, JackThreadInitCallback thread_init_callback, void *arg), (client, thread_init_callback, arg)); DECL_FUNCTION(int, jack_set_freewheel_callback, (jack_client_t *client, JackFreewheelCallback freewheel_callback, void *arg), (client, freewheel_callback, arg)); DECL_FUNCTION(int, jack_set_freewheel, (jack_client_t *client, int onoff), (client, onoff)); DECL_FUNCTION(int, jack_set_buffer_size, (jack_client_t *client, jack_nframes_t nframes), (client, nframes)); DECL_FUNCTION(int, jack_set_buffer_size_callback, (jack_client_t *client, JackBufferSizeCallback bufsize_callback, void *arg), (client, bufsize_callback, arg)); DECL_FUNCTION(int, jack_set_sample_rate_callback, (jack_client_t *client, JackSampleRateCallback srate_callback, void *arg), (client, srate_callback, arg)); DECL_FUNCTION(int, jack_set_client_registration_callback, (jack_client_t *client, JackClientRegistrationCallback registration_callback, void *arg), (client, registration_callback, arg)); DECL_FUNCTION(int, jack_set_port_registration_callback, (jack_client_t *client, JackPortRegistrationCallback registration_callback, void *arg), (client, registration_callback, arg)); DECL_FUNCTION(int, jack_set_port_connect_callback, (jack_client_t *client, JackPortConnectCallback connect_callback, void *arg), (client, connect_callback, arg)); DECL_FUNCTION(int, jack_set_port_rename_callback, (jack_client_t *client, JackPortRenameCallback rename_callback, void *arg), (client, rename_callback, arg)); DECL_FUNCTION(int, jack_set_graph_order_callback, (jack_client_t *client, JackGraphOrderCallback graph_callback, void *arg), (client, graph_callback, arg)); DECL_FUNCTION(int, jack_set_xrun_callback, (jack_client_t *client, JackXRunCallback xrun_callback, void *arg), (client, xrun_callback, arg)); DECL_FUNCTION(int, jack_set_latency_callback, (jack_client_t *client, JackLatencyCallback latency_callback, void *arg), (client, latency_callback, arg)); DECL_FUNCTION(int, jack_activate, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_deactivate, (jack_client_t *client), (client)); DECL_FUNCTION_NULL(jack_port_t *, jack_port_register, (jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size), (client, port_name, port_type, flags, buffer_size)); DECL_FUNCTION(int, jack_port_unregister, (jack_client_t *client, jack_port_t* port), (client, port)); DECL_FUNCTION_NULL(void *, jack_port_get_buffer, (jack_port_t *port, jack_nframes_t nframes), (port, nframes)); DECL_FUNCTION_NULL(const char*, jack_port_name, (const jack_port_t *port), (port)); DECL_FUNCTION_NULL(const char*, jack_port_short_name, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_flags, (const jack_port_t *port), (port)); DECL_FUNCTION_NULL(const char*, jack_port_type, (const jack_port_t *port), (port)); DECL_FUNCTION(jack_port_type_id_t, jack_port_type_id, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_is_mine, (const jack_client_t *client, const jack_port_t* port), (client, port)); DECL_FUNCTION(int, jack_port_connected, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_connected_to, (const jack_port_t *port, const char *port_name), (port, port_name)); DECL_FUNCTION_NULL(const char**, jack_port_get_connections, (const jack_port_t *port), (port)); DECL_FUNCTION_NULL(const char**, jack_port_get_all_connections, (const jack_client_t *client,const jack_port_t *port), (client, port)); DECL_FUNCTION(int, jack_port_tie, (jack_port_t *src, jack_port_t *dst), (src, dst)); DECL_FUNCTION(int, jack_port_untie, (jack_port_t *port), (port)); DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port), (port)); DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t * client, jack_port_t *port), (client, port)); DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t * port, jack_nframes_t frames), (port, frames)); DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t* client, jack_port_t* port), (client, port)); DECL_VOID_FUNCTION(jack_port_get_latency_range, (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range), (port, mode, range)); DECL_VOID_FUNCTION(jack_port_set_latency_range, (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range), (port, mode, range)); DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t* client),(client)); DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port, const char *port_name), (port, port_name)); DECL_FUNCTION(int, jack_port_rename, (jack_client_t *client, jack_port_t *port, const char *port_name), (client, port, port_name)); DECL_FUNCTION(int, jack_port_set_alias, (jack_port_t *port, const char *alias), (port, alias)); DECL_FUNCTION(int, jack_port_unset_alias, (jack_port_t *port, const char *alias), (port, alias)); DECL_FUNCTION(int, jack_port_get_aliases, (const jack_port_t *port, char* const aliases[2]), (port,aliases)); DECL_FUNCTION(int, jack_port_request_monitor, (jack_port_t *port, int onoff), (port, onoff)); DECL_FUNCTION(int, jack_port_request_monitor_by_name, (jack_client_t *client, const char *port_name, int onoff), (client, port_name, onoff)); DECL_FUNCTION(int, jack_port_ensure_monitor, (jack_port_t *port, int onoff), (port, onoff)); DECL_FUNCTION(int, jack_port_monitoring_input, (jack_port_t *port) ,(port)); DECL_FUNCTION(int, jack_connect, (jack_client_t * client, const char *source_port, const char *destination_port), (client, source_port, destination_port)); DECL_FUNCTION(int, jack_disconnect, (jack_client_t * client, const char *source_port, const char *destination_port), (client, source_port, destination_port)); DECL_FUNCTION(int, jack_port_disconnect, (jack_client_t * client, jack_port_t * port), (client, port)); DECL_FUNCTION(int, jack_port_name_size,(),()); DECL_FUNCTION(int, jack_port_type_size,(),()); DECL_FUNCTION(size_t, jack_port_type_get_buffer_size, (jack_client_t *client, const char* port_type), (client, port_type)); DECL_FUNCTION(jack_nframes_t, jack_get_sample_rate, (jack_client_t *client), (client)); DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client)); DECL_FUNCTION_NULL(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); DECL_FUNCTION_NULL(jack_port_t *, jack_port_by_name, (jack_client_t * client, const char *port_name), (client, port_name)); DECL_FUNCTION_NULL(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id)); DECL_FUNCTION(int, jack_engine_takeover_timebase, (jack_client_t * client), (client)); DECL_FUNCTION(jack_nframes_t, jack_frames_since_cycle_start, (const jack_client_t * client), (client)); DECL_FUNCTION(jack_time_t, jack_get_time, (), ()); DECL_FUNCTION(jack_nframes_t, jack_time_to_frames, (const jack_client_t *client, jack_time_t time), (client, time)); DECL_FUNCTION(jack_time_t, jack_frames_to_time, (const jack_client_t *client, jack_nframes_t frames), (client, frames)); DECL_FUNCTION(jack_nframes_t, jack_frame_time, (const jack_client_t *client), (client)); DECL_FUNCTION(jack_nframes_t, jack_last_frame_time, (const jack_client_t *client), (client)); DECL_FUNCTION(float, jack_cpu_load, (jack_client_t *client), (client)); DECL_FUNCTION_NULL(jack_native_thread_t, jack_client_thread_id, (jack_client_t *client), (client)); DECL_VOID_FUNCTION(jack_set_error_function, (print_function fun), (fun)); DECL_VOID_FUNCTION(jack_set_info_function, (print_function fun), (fun)); DECL_FUNCTION(float, jack_get_max_delayed_usecs, (jack_client_t *client), (client)); DECL_FUNCTION(float, jack_get_xrun_delayed_usecs, (jack_client_t *client), (client)); DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_release_timebase, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_set_sync_callback, (jack_client_t *client, JackSyncCallback sync_callback, void *arg), (client, sync_callback, arg)); DECL_FUNCTION(int, jack_set_sync_timeout, (jack_client_t *client, jack_time_t timeout), (client, timeout)); DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client, int conditional, JackTimebaseCallback timebase_callback, void *arg), (client, conditional, timebase_callback, arg)); DECL_FUNCTION(int, jack_transport_locate, (jack_client_t *client, jack_nframes_t frame), (client, frame)); DECL_FUNCTION(jack_transport_state_t, jack_transport_query, (const jack_client_t *client, jack_position_t *pos), (client, pos)); DECL_FUNCTION(jack_nframes_t, jack_get_current_transport_frame, (const jack_client_t *client), (client)); DECL_FUNCTION(int, jack_transport_reposition, (jack_client_t *client, const jack_position_t *pos), (client, pos)); DECL_VOID_FUNCTION(jack_transport_start, (jack_client_t *client), (client)); DECL_VOID_FUNCTION(jack_transport_stop, (jack_client_t *client), (client)); DECL_VOID_FUNCTION(jack_get_transport_info, (jack_client_t *client, jack_transport_info_t *tinfo), (client,tinfo)); DECL_VOID_FUNCTION(jack_set_transport_info, (jack_client_t *client, jack_transport_info_t *tinfo), (client,tinfo)); DECL_FUNCTION(int, jack_client_real_time_priority, (jack_client_t* client), (client)); DECL_FUNCTION(int, jack_client_max_real_time_priority, (jack_client_t* client), (client)); DECL_FUNCTION(int, jack_acquire_real_time_scheduling, (jack_native_thread_t thread, int priority), (thread, priority)); DECL_FUNCTION(int, jack_client_create_thread, (jack_client_t* client, jack_native_thread_t *thread, int priority, int realtime, // boolean thread_routine routine, void *arg), (client, thread, priority, realtime, routine, arg)); DECL_FUNCTION(int, jack_drop_real_time_scheduling, (jack_native_thread_t thread), (thread)); DECL_FUNCTION(int, jack_client_stop_thread, (jack_client_t* client, jack_native_thread_t thread), (client, thread)); DECL_FUNCTION(int, jack_client_kill_thread, (jack_client_t* client, jack_native_thread_t thread), (client, thread)); #ifndef WIN32 DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc), (jtc)); #endif DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); DECL_FUNCTION(jack_intclient_t, jack_internal_client_handle, (jack_client_t *client, const char *client_name, jack_status_t *status), (client, client_name, status)); /* DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client, const char *client_name, jack_options_t options, jack_status_t *status , ...), (client, client_name, options, status, ...)); */ DECL_FUNCTION(jack_status_t, jack_internal_client_unload, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); DECL_VOID_FUNCTION(jack_free, (void* ptr), (ptr)); // session DECL_FUNCTION(int, jack_set_session_callback, (jack_client_t* ext_client, JackSessionCallback session_callback, void* arg), (ext_client, session_callback, arg)); DECL_FUNCTION(jack_session_command_t*, jack_session_notify, (jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path), (ext_client, target, ev_type, path)); DECL_FUNCTION(int, jack_session_reply, (jack_client_t* ext_client, jack_session_event_t *event), (ext_client, event)); DECL_VOID_FUNCTION(jack_session_event_free, (jack_session_event_t* ev), (ev)); DECL_FUNCTION(char*, jack_client_get_uuid, (jack_client_t* ext_client),(ext_client)); DECL_FUNCTION(char*, jack_get_uuid_for_client_name, (jack_client_t* ext_client, const char* client_name),(ext_client, client_name)); DECL_FUNCTION(char*, jack_get_client_name_by_uuid, (jack_client_t* ext_client, const char* client_uuid),(ext_client, client_uuid)); DECL_FUNCTION(int, jack_reserve_client_name, (jack_client_t* ext_client, const char* name, const char* uuid),(ext_client, name, uuid)); DECL_VOID_FUNCTION(jack_session_commands_free, (jack_session_command_t *cmds),(cmds)); DECL_FUNCTION(int, jack_client_has_session_callback, (jack_client_t *client, const char* client_name),(client, client_name)); // MIDI DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer), (port_buffer)); DECL_FUNCTION(int, jack_midi_event_get, (jack_midi_event_t* event, void* port_buffer, jack_nframes_t event_index), (event, port_buffer, event_index)) ; DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer), (port_buffer)); DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer), (port_buffer)); DECL_FUNCTION_NULL(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer, jack_nframes_t time, size_t data_size), (port_buffer, time, data_size)); DECL_FUNCTION(int, jack_midi_event_write, (void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size), (port_buffer, time, data, data_size)); DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer), (port_buffer)); 1.9.12~dfsg/common/netjack.c0000644000000000000000000007607713214314510014434 0ustar rootroot /* -*- mode: c; c-file-style: "linux"; -*- */ /* NetJack Abstraction. Copyright (C) 2008 Pieter Palmers Copyright (C) 2006 Torben Hohn Copyright (C) 2003 Robert Ham Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ */ #include #include #include #include #include #include #include #include #include "jack/jslist.h" #include #ifdef WIN32 #include #include #define socklen_t int #else #include #include #endif #if defined(HAVE_CONFIG_H) #include "config.h" #endif #if HAVE_SAMPLERATE #include #endif #include "netjack.h" #include "netjack_packet.h" #include "JackError.h" #define MIN(x,y) ((x)<(y) ? (x) : (y)) static int sync_state = 1; static jack_transport_state_t last_transport_state; static int net_driver_sync_cb(jack_transport_state_t state, jack_position_t *pos, void *data) { int retval = sync_state; if (state == JackTransportStarting && last_transport_state != JackTransportStarting) { retval = 0; } // if (state == JackTransportStarting) // jack_info("Starting sync_state = %d", sync_state); last_transport_state = state; return retval; } int netjack_wait( netjack_driver_state_t *netj ) { int we_have_the_expected_frame = 0; jack_nframes_t next_frame_avail; jack_time_t packet_recv_time_stamp; jacknet_packet_header *pkthdr; if( !netj->next_deadline_valid ) { netj->next_deadline = jack_get_time() + netj->period_usecs; netj->next_deadline_valid = 1; } // Increment expected frame here. if( netj->expected_framecnt_valid ) { netj->expected_framecnt += 1; } else { // starting up.... lets look into the packetcache, and fetch the highest packet. packet_cache_drain_socket( netj->packcache, netj->sockfd ); if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) { netj->expected_framecnt = next_frame_avail; netj->expected_framecnt_valid = 1; } else { // no packets there... start normally. netj->expected_framecnt = 0; netj->expected_framecnt_valid = 1; } } //jack_log( "expect %d", netj->expected_framecnt ); // Now check if required packet is already in the cache. // then poll (have deadline calculated) // then drain socket, rinse and repeat. while(1) { if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) { if( next_frame_avail == netj->expected_framecnt ) { we_have_the_expected_frame = 1; if( !netj->always_deadline ) break; } } if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) { break; } packet_cache_drain_socket( netj->packcache, netj->sockfd ); } // check if we know who to send our packets too. if (!netj->srcaddress_valid) if( netj->packcache->master_address_valid ) { memcpy (&(netj->syncsource_address), &(netj->packcache->master_address), sizeof( struct sockaddr_in ) ); netj->srcaddress_valid = 1; } // XXX: switching mode unconditionally is stupid. // if we were running free perhaps we like to behave differently // ie. fastforward one packet etc. // well... this is the first packet we see. hmm.... dunno ;S // it works... so... netj->running_free = 0; //if( !we_have_the_expected_frame ) // jack_error( "netxrun... %d", netj->expected_framecnt ); if( we_have_the_expected_frame ) { jack_time_t now = jack_get_time(); if( now < netj->next_deadline ) netj->time_to_deadline = netj->next_deadline - now; else netj->time_to_deadline = 0; packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp); pkthdr = (jacknet_packet_header *) netj->rx_buf; packet_header_ntoh(pkthdr); netj->deadline_goodness = (int)pkthdr->sync_state; netj->packet_data_valid = 1; int want_deadline; if( netj->jitter_val != 0 ) want_deadline = netj->jitter_val; else if( netj->latency < 4 ) want_deadline = -netj->period_usecs / 2; else want_deadline = (netj->period_usecs / 4 + 10 * (int)netj->period_usecs * netj->latency / 100); if( netj->deadline_goodness != MASTER_FREEWHEELS ) { if( netj->deadline_goodness < want_deadline ) { netj->next_deadline -= netj->period_usecs / 100; //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); } if( netj->deadline_goodness > want_deadline ) { netj->next_deadline += netj->period_usecs / 100; //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); } } // if( netj->next_deadline < (netj->period_usecs*70/100) ) { // jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); // netj->deadline_offset = (netj->period_usecs*90/100); // } netj->next_deadline += netj->period_usecs; } else { netj->time_to_deadline = 0; netj->next_deadline += netj->period_usecs; // bah... the packet is not there. // either // - it got lost. // - its late // - sync source is not sending anymore. // lets check if we have the next packets, we will just run a cycle without data. // in that case. if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) { jack_nframes_t offset = next_frame_avail - netj->expected_framecnt; //XXX: hmm... i need to remember why resync_threshold wasnt right. //if( offset < netj->resync_threshold ) if( offset < 10 ) { // ok. dont do nothing. we will run without data. // this seems to be one or 2 lost packets. // // this can also be reordered packet jitter. // (maybe this is not happening in real live) // but it happens in netem. netj->packet_data_valid = 0; // I also found this happening, when the packet queue, is too full. // but wtf ? use a smaller latency. this link can handle that ;S if( packet_cache_get_fill( netj->packcache, netj->expected_framecnt ) > 80.0 ) netj->next_deadline -= netj->period_usecs / 2; } else { // the diff is too high. but we have a packet in the future. // lets resync. netj->expected_framecnt = next_frame_avail; packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL ); pkthdr = (jacknet_packet_header *) netj->rx_buf; packet_header_ntoh(pkthdr); //netj->deadline_goodness = 0; netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset; netj->next_deadline_valid = 0; netj->packet_data_valid = 1; } } else { // no packets in buffer. netj->packet_data_valid = 0; //printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets ); if( netj->num_lost_packets < 5 ) { // ok. No Packet in queue. The packet was either lost, // or we are running too fast. // // Adjusting the deadline unconditionally resulted in // too many xruns on master. // But we need to adjust for the case we are running too fast. // So lets check if the last packet is there now. // // It would not be in the queue anymore, if it had been // retrieved. This might break for redundancy, but // i will make the packet cache drop redundant packets, // that have already been retreived. // if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) { if( next_frame_avail == (netj->expected_framecnt - 1) ) { // Ok. the last packet is there now. // and it had not been retrieved. // // TODO: We are still dropping 2 packets. // perhaps we can adjust the deadline // when (num_packets lost == 0) // This might still be too much. netj->next_deadline += netj->period_usecs; } } } else if( (netj->num_lost_packets <= 100) ) { // lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast. netj->next_deadline += netj->period_usecs * netj->latency / 8; } else { // But now we can check for any new frame available. // if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) { netj->expected_framecnt = next_frame_avail; packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL ); pkthdr = (jacknet_packet_header *) netj->rx_buf; packet_header_ntoh(pkthdr); netj->deadline_goodness = pkthdr->sync_state; netj->next_deadline_valid = 0; netj->packet_data_valid = 1; netj->running_free = 0; jack_info( "resync after freerun... %d", netj->expected_framecnt ); } else { if( netj->num_lost_packets == 101 ) { jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt ); } netj->running_free = 1; // when we really dont see packets. // reset source address. and open possibility for new master. // maybe dsl reconnect. Also restart of netsource without fix // reply address changes port. if (netj->num_lost_packets > 200 ) { netj->srcaddress_valid = 0; packet_cache_reset_master_address( netj->packcache ); } } } } } int retval = 0; if( !netj->packet_data_valid ) { netj->num_lost_packets += 1; if( netj->num_lost_packets == 1 ) retval = netj->period_usecs; } else { if( (netj->num_lost_packets > 1) && !netj->running_free ) retval = (netj->num_lost_packets - 1) * netj->period_usecs; netj->num_lost_packets = 0; } return retval; } void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ) { int tx_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up + sizeof(jacknet_packet_header); unsigned int *packet_buf, *packet_bufX; packet_buf = alloca( tx_size); jacknet_packet_header *tx_pkthdr = (jacknet_packet_header *)packet_buf; jacknet_packet_header *rx_pkthdr = (jacknet_packet_header *)netj->rx_buf; //framecnt = rx_pkthdr->framecnt; netj->reply_port = rx_pkthdr->reply_port; // offset packet_bufX by the packetheader. packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); tx_pkthdr->sync_state = syncstate; tx_pkthdr->framecnt = netj->expected_framecnt; // memset 0 the payload. int payload_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up; memset(packet_bufX, 0, payload_size); packet_header_hton(tx_pkthdr); if (netj->srcaddress_valid) { int r; if (netj->reply_port) netj->syncsource_address.sin_port = htons(netj->reply_port); for( r = 0; r < netj->redundancy; r++ ) netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size, 0, (struct sockaddr*) & (netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu); } } void netjack_attach( netjack_driver_state_t *netj ) { //puts ("net_driver_attach"); jack_port_t * port; char buf[32]; unsigned int chn; int port_flags; if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 celt_int32 lookahead; netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); #else celt_int32_t lookahead; netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); #endif celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); netj->codec_latency = 2 * lookahead; #endif } if( netj->bitdepth == OPUS_MODE ) { #if HAVE_OPUS netj->opus_mode = opus_custom_mode_create(netj->sample_rate, netj->period_size, NULL); #endif } if (netj->handle_transport_sync) jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL); port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; for (chn = 0; chn < netj->capture_channels_audio; chn++) { snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); port = jack_port_register (netj->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); if (!port) { jack_error ("NET: cannot register port for %s", buf); break; } netj->capture_ports = jack_slist_append (netj->capture_ports, port); if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_11 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) ); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) ); #else netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) ); #endif #endif } else if( netj->bitdepth == OPUS_MODE ) { #if HAVE_OPUS OpusCustomDecoder *decoder = opus_custom_decoder_create( netj->opus_mode, 1, NULL ); netj->capture_srcs = jack_slist_append(netj->capture_srcs, decoder ); #endif } else { #if HAVE_SAMPLERATE netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL)); #endif } } for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) { snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); port = jack_port_register (netj->client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); if (!port) { jack_error ("NET: cannot register port for %s", buf); break; } netj->capture_ports = jack_slist_append (netj->capture_ports, port); } port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for (chn = 0; chn < netj->playback_channels_audio; chn++) { snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); port = jack_port_register (netj->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); if (!port) { jack_error ("NET: cannot register port for %s", buf); break; } netj->playback_ports = jack_slist_append (netj->playback_ports, port); if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_11 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); #else CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) ); #endif #endif } else if( netj->bitdepth == OPUS_MODE ) { #if HAVE_OPUS const int kbps = netj->resample_factor; jack_log( "OPUS %dkbps\n", kbps); OpusCustomMode *opus_mode = opus_custom_mode_create( netj->sample_rate, netj->period_size, NULL ); // XXX free me in the end OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, NULL ); opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10)); opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY)); netj->playback_srcs = jack_slist_append(netj->playback_srcs, oe ); #endif } else { #if HAVE_SAMPLERATE netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL)); #endif } } for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) { snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); port = jack_port_register (netj->client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); if (!port) { jack_error ("NET: cannot register port for %s", buf); break; } netj->playback_ports = jack_slist_append (netj->playback_ports, port); } jack_activate (netj->client); } void netjack_detach( netjack_driver_state_t *netj ) { JSList * node; for (node = netj->capture_ports; node; node = jack_slist_next (node)) jack_port_unregister (netj->client, ((jack_port_t *) node->data)); jack_slist_free (netj->capture_ports); netj->capture_ports = NULL; for (node = netj->capture_srcs; node; node = jack_slist_next (node)) { #if HAVE_CELT if( netj->bitdepth == CELT_MODE ) { CELTDecoder * decoder = node->data; celt_decoder_destroy(decoder); } else #endif #if HAVE_OPUS if ( netj->bitdepth == OPUS_MODE ) { OpusCustomDecoder * decoder = node->data; opus_custom_decoder_destroy(decoder); } else #endif { #if HAVE_SAMPLERATE SRC_STATE * src = node->data; src_delete(src); #endif } } jack_slist_free (netj->capture_srcs); netj->playback_srcs = NULL; for (node = netj->playback_ports; node; node = jack_slist_next (node)) jack_port_unregister (netj->client, ((jack_port_t *) node->data)); jack_slist_free (netj->playback_ports); netj->playback_ports = NULL; for (node = netj->playback_srcs; node; node = jack_slist_next (node)) { #if HAVE_CELT if( netj->bitdepth == CELT_MODE ) { CELTEncoder * encoder = node->data; celt_encoder_destroy(encoder); } else #endif #if HAVE_OPUS if ( netj->bitdepth == OPUS_MODE ) { OpusCustomEncoder * encoder = node->data; opus_custom_encoder_destroy(encoder); } else #endif { #if HAVE_SAMPLERATE SRC_STATE * src = node->data; src_delete(src); #endif } } jack_slist_free (netj->playback_srcs); netj->playback_srcs = NULL; #if HAVE_CELT if( netj->bitdepth == CELT_MODE ) celt_mode_destroy(netj->celt_mode); #endif #if HAVE_OPUS if( netj->bitdepth == OPUS_MODE ) opus_custom_mode_destroy(netj->opus_mode); #endif } netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, jack_client_t * client, const char *name, unsigned int capture_ports, unsigned int playback_ports, unsigned int capture_ports_midi, unsigned int playback_ports_midi, jack_nframes_t sample_rate, jack_nframes_t period_size, unsigned int listen_port, unsigned int transport_sync, unsigned int resample_factor, unsigned int resample_factor_up, unsigned int bitdepth, unsigned int use_autoconfig, unsigned int latency, unsigned int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ) { // Fill in netj values. // might be subject to autoconfig... // so dont calculate anything with them... netj->sample_rate = sample_rate; netj->period_size = period_size; netj->dont_htonl_floats = dont_htonl_floats; netj->listen_port = listen_port; netj->capture_channels = capture_ports + capture_ports_midi; netj->capture_channels_audio = capture_ports; netj->capture_channels_midi = capture_ports_midi; netj->capture_ports = NULL; netj->playback_channels = playback_ports + playback_ports_midi; netj->playback_channels_audio = playback_ports; netj->playback_channels_midi = playback_ports_midi; netj->playback_ports = NULL; netj->codec_latency = 0; netj->handle_transport_sync = transport_sync; netj->mtu = 1400; netj->latency = latency; netj->redundancy = redundancy; netj->use_autoconfig = use_autoconfig; netj->always_deadline = always_deadline; netj->client = client; if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE) && (bitdepth != OPUS_MODE)) { jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth); return NULL; } netj->bitdepth = bitdepth; if (resample_factor_up == 0) { resample_factor_up = resample_factor; } netj->resample_factor = resample_factor; netj->resample_factor_up = resample_factor_up; netj->jitter_val = jitter_val; netj->playback_srcs = NULL; netj->capture_srcs = NULL; return netj; } void netjack_release( netjack_driver_state_t *netj ) { close( netj->sockfd ); close( netj->outsockfd ); packet_cache_free( netj->packcache ); netj->packcache = NULL; } int netjack_startup( netjack_driver_state_t *netj ) { int first_pack_len; struct sockaddr_in address; // Now open the socket, and wait for the first packet to arrive... netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0); #ifdef WIN32 if (netj->sockfd == INVALID_SOCKET) #else if (netj->sockfd == -1) #endif { jack_info ("socket error"); return -1; } address.sin_family = AF_INET; address.sin_port = htons(netj->listen_port); address.sin_addr.s_addr = htonl(INADDR_ANY); if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0) { jack_info("bind error"); return -1; } netj->outsockfd = socket (AF_INET, SOCK_DGRAM, 0); #ifdef WIN32 if (netj->outsockfd == INVALID_SOCKET) #else if (netj->outsockfd == -1) #endif { jack_info ("socket error"); return -1; } netj->srcaddress_valid = 0; if (netj->use_autoconfig) { jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header)); #ifdef WIN32 int address_size = sizeof( struct sockaddr_in ); #else socklen_t address_size = sizeof (struct sockaddr_in); #endif //jack_info ("Waiting for an incoming packet !!!"); //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!"); while(1) { if( ! netjack_poll( netj->sockfd, 1000 ) ) { jack_info ("Waiting aborted"); return -1; } first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); #ifdef WIN32 if( first_pack_len == -1 ) { first_pack_len = sizeof(jacknet_packet_header); break; } #else if (first_pack_len == sizeof (jacknet_packet_header)) break; #endif } netj->srcaddress_valid = 1; if (first_pack_len == sizeof (jacknet_packet_header)) { packet_header_ntoh (first_packet); jack_info ("AutoConfig Override !!!"); if (netj->sample_rate != first_packet->sample_rate) { jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate); netj->sample_rate = first_packet->sample_rate; } if (netj->period_size != first_packet->period_size) { jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size); netj->period_size = first_packet->period_size; } if (netj->capture_channels_audio != first_packet->capture_channels_audio) { jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio); netj->capture_channels_audio = first_packet->capture_channels_audio; } if (netj->capture_channels_midi != first_packet->capture_channels_midi) { jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi); netj->capture_channels_midi = first_packet->capture_channels_midi; } if (netj->playback_channels_audio != first_packet->playback_channels_audio) { jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio); netj->playback_channels_audio = first_packet->playback_channels_audio; } if (netj->playback_channels_midi != first_packet->playback_channels_midi) { jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi); netj->playback_channels_midi = first_packet->playback_channels_midi; } netj->mtu = first_packet->mtu; jack_info ("MTU is set to %d bytes", first_packet->mtu); netj->latency = first_packet->latency; } } netj->capture_channels = netj->capture_channels_audio + netj->capture_channels_midi; netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi; if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) { jack_error( "autoconfig requests more than 100MB packet cache... bailing out" ); exit(1); } if( netj->playback_channels > 1000 ) { jack_error( "autoconfig requests more than 1000 playback channels... bailing out" ); exit(1); } if( netj->mtu < (2 * sizeof( jacknet_packet_header )) ) { jack_error( "bullshit mtu requested by autoconfig" ); exit(1); } if( netj->sample_rate == 0 ) { jack_error( "sample_rate 0 requested by autoconfig" ); exit(1); } // After possible Autoconfig: do all calculations... netj->period_usecs = (jack_time_t) floor ((((float) netj->period_size) / (float)netj->sample_rate) * 1000000.0f); if( netj->latency == 0 ) netj->deadline_offset = 50 * netj->period_usecs; else netj->deadline_offset = netj->period_usecs + 10 * netj->latency * netj->period_usecs / 100; if( netj->bitdepth == CELT_MODE ) { // celt mode. // TODO: this is a hack. But i dont want to change the packet header. netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1); netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1); netj->net_period_down = netj->resample_factor; netj->net_period_up = netj->resample_factor_up; } else if( netj->bitdepth == OPUS_MODE ) { // Opus mode. // TODO: this is a hack. But i dont want to change the packet header, either netj->net_period_down = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1); netj->net_period_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1); } else { netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor; netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up; } netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth); netj->packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu); netj->expected_framecnt_valid = 0; netj->num_lost_packets = 0; netj->next_deadline_valid = 0; netj->deadline_goodness = 0; netj->time_to_deadline = 0; // Special handling for latency=0 if( netj->latency == 0 ) netj->resync_threshold = 0; else netj->resync_threshold = MIN( 15, netj->latency - 1 ); netj->running_free = 0; return 0; } 1.9.12~dfsg/common/JackMessageBuffer.cpp0000644000000000000000000001233613214314510016650 0ustar rootroot/* * Copyright (C) 2004 Rui Nuno Capela, Steve Harris * Copyright (C) 2008 Nedko Arnaudov * Copyright (C) 2008 Grame * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include "JackMessageBuffer.h" #include "JackGlobals.h" #include "JackError.h" #include "JackTime.h" namespace Jack { JackMessageBuffer* JackMessageBuffer::fInstance = NULL; JackMessageBuffer::JackMessageBuffer() :fInit(NULL), fInitArg(NULL), fThread(this), fGuard(), fInBuffer(0), fOutBuffer(0), fOverruns(0), fRunning(false) {} JackMessageBuffer::~JackMessageBuffer() {} bool JackMessageBuffer::Start() { // Before StartSync()... fRunning = true; if (fThread.StartSync() == 0) { return true; } else { fRunning = false; return false; } } bool JackMessageBuffer::Stop() { if (fOverruns > 0) { jack_error("WARNING: %d message buffer overruns!", fOverruns); } else { jack_log("no message buffer overruns"); } if (fGuard.Lock()) { fRunning = false; fGuard.Signal(); fGuard.Unlock(); fThread.Stop(); } else { fThread.Kill(); } Flush(); return true; } void JackMessageBuffer::Flush() { while (fOutBuffer != fInBuffer) { jack_log_function(fBuffers[fOutBuffer].level, fBuffers[fOutBuffer].message); fOutBuffer = MB_NEXT(fOutBuffer); } } void JackMessageBuffer::AddMessage(int level, const char *message) { if (fGuard.Trylock()) { fBuffers[fInBuffer].level = level; strncpy(fBuffers[fInBuffer].message, message, MB_BUFFERSIZE); fInBuffer = MB_NEXT(fInBuffer); fGuard.Signal(); fGuard.Unlock(); } else { /* lock collision */ INC_ATOMIC(&fOverruns); } } bool JackMessageBuffer::Execute() { if (fGuard.Lock()) { while (fRunning) { fGuard.Wait(); /* the client asked for all threads to run a thread initialization callback, which includes us. */ if (fInit) { fInit(fInitArg); fInit = NULL; /* and we're done */ fGuard.Signal(); } /* releasing the mutex reduces contention */ fGuard.Unlock(); Flush(); fGuard.Lock(); } fGuard.Unlock(); } else { jack_error("JackMessageBuffer::Execute lock cannot be taken"); } return false; } bool JackMessageBuffer::Create() { if (fInstance == NULL) { fInstance = new JackMessageBuffer(); if (!fInstance->Start()) { jack_error("JackMessageBuffer::Create cannot start thread"); delete fInstance; fInstance = NULL; return false; } } return true; } bool JackMessageBuffer::Destroy() { if (fInstance != NULL) { fInstance->Stop(); delete fInstance; fInstance = NULL; return true; } else { return false; } } void JackMessageBufferAdd(int level, const char *message) { if (Jack::JackMessageBuffer::fInstance == NULL) { /* Unable to print message with realtime safety. Complain and print it anyway. */ jack_log_function(LOG_LEVEL_ERROR, "messagebuffer not initialized, skip message"); } else { Jack::JackMessageBuffer::fInstance->AddMessage(level, message); } } int JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *arg) { if (fInstance && callback && fRunning && fGuard.Lock()) { /* set up the callback */ fInitArg = arg; fInit = callback; #ifndef WIN32 // wake msg buffer thread fGuard.Signal(); // wait for it to be done fGuard.Wait(); // and we're done fGuard.Unlock(); #else /* The condition variable emulation code does not work reliably on Windows (lost signal). So use a "hackish" way to signal/wait for the result. Probaly better in the long term : use pthread-win32 (http://sourceware.org/pthreads-win32/` */ fGuard.Unlock(); int count = 0; while (fInit && ++count < 1000) { /* wake msg buffer thread */ fGuard.Signal(); JackSleep(1000); } if (count == 1000) { jack_error("JackMessageBuffer::SetInitCallback : signal lost"); return -1; } #endif return 0; } jack_error("JackMessageBuffer::SetInitCallback : callback could not be executed"); return -1; } }; 1.9.12~dfsg/common/JackShmMem.h0000644000000000000000000002314013214314510014760 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackShmMem__ #define __JackShmMem__ #include "shm.h" #include "JackError.h" #include "JackCompilerDeps.h" #include // GCC 4.0 #include #include #include "JackShmMem_os.h" namespace Jack { void LockMemoryImp(void* ptr, size_t size); void InitLockMemoryImp(void* ptr, size_t size); void UnlockMemoryImp(void* ptr, size_t size); void LockAllMemory(); void UnlockAllMemory(); class JackMem { private: size_t fSize; static size_t gSize; protected: JackMem(): fSize(gSize) {} ~JackMem() {} public: void* operator new(size_t size) { gSize = size; return calloc(1, size); } void operator delete(void* ptr, size_t size) { free(ptr); } void LockMemory() { LockMemoryImp(this, fSize); } void UnlockMemory() { UnlockMemoryImp(this, fSize); } }; /*! \brief A class which objects possibly want to be allocated in shared memory derives from this class. */ class JackShmMemAble { protected: jack_shm_info_t fInfo; public: void Init(); int GetShmIndex() { return fInfo.index; } char* GetShmAddress() { return (char*)fInfo.ptr.attached_at; } void LockMemory() { LockMemoryImp(this, fInfo.size); } void UnlockMemory() { UnlockMemoryImp(this, fInfo.size); } }; /*! \brief The base class for shared memory management. A class which objects need to be allocated in shared memory derives from this class. */ class SERVER_EXPORT JackShmMem : public JackShmMemAble { protected: JackShmMem(); ~JackShmMem(); public: void* operator new(size_t size); void* operator new(size_t size, void* memory); void operator delete(void* p, size_t size); void operator delete(void* p); }; /*! \brief Pointer on shared memory segment in the client side. */ template class JackShmReadWritePtr { private: jack_shm_info_t fInfo; bool fInitDone; void Init(int index, const char* server_name = JACK_DEFAULT_SERVER_NAME) { if (fInfo.index < 0 && index >= 0) { jack_log("JackShmReadWritePtr::Init %ld %d", index, fInfo.index); if (jack_initialize_shm(server_name) < 0) { throw std::bad_alloc(); } fInfo.index = index; if (jack_attach_lib_shm(&fInfo)) { throw std::bad_alloc(); } GetShmAddress()->LockMemory(); fInitDone = true; } } public: JackShmReadWritePtr() { fInfo.index = -1; fInitDone = false; fInfo.ptr.attached_at = (char*)NULL; } JackShmReadWritePtr(int index, const char* server_name) { Init(index, server_name); } ~JackShmReadWritePtr() { if (!fInitDone) { jack_error("JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for %d, skipping unlock", fInfo.index); return; } if (fInfo.index >= 0) { jack_log("JackShmReadWritePtr::~JackShmReadWritePtr %d", fInfo.index); GetShmAddress()->UnlockMemory(); jack_release_lib_shm(&fInfo); fInfo.index = -1; } } T* operator->() const { return (T*)fInfo.ptr.attached_at; } operator T*() const { return (T*)fInfo.ptr.attached_at; } JackShmReadWritePtr& operator=(int index) { Init(index); return *this; } void SetShmIndex(int index, const char* server_name) { Init(index, server_name); } int GetShmIndex() { return fInfo.index; } T* GetShmAddress() { return (T*)fInfo.ptr.attached_at; } }; /*! \brief Pointer on shared memory segment in the client side: destroy the segment (used client control) */ template class JackShmReadWritePtr1 { private: jack_shm_info_t fInfo; bool fInitDone; void Init(int index, const char* server_name = JACK_DEFAULT_SERVER_NAME) { if (fInfo.index < 0 && index >= 0) { jack_log("JackShmReadWritePtr1::Init %ld %d", index, fInfo.index); if (jack_initialize_shm(server_name) < 0) { throw std::bad_alloc(); } fInfo.index = index; if (jack_attach_lib_shm(&fInfo)) { throw std::bad_alloc(); } GetShmAddress()->LockMemory(); fInitDone = true; /* nobody else needs to access this shared memory any more, so destroy it. because we have our own attachment to it, it won't vanish till we exit (and release it). */ jack_destroy_shm(&fInfo); } } public: JackShmReadWritePtr1() { fInfo.index = -1; fInitDone = false; fInfo.ptr.attached_at = NULL; } JackShmReadWritePtr1(int index, const char* server_name) { Init(index, server_name); } ~JackShmReadWritePtr1() { if (!fInitDone) { jack_error("JackShmReadWritePtr1::~JackShmReadWritePtr1 - Init not done for %d, skipping unlock", fInfo.index); return; } if (fInfo.index >= 0) { jack_log("JackShmReadWritePtr1::~JackShmReadWritePtr1 %d", fInfo.index); GetShmAddress()->UnlockMemory(); jack_release_lib_shm(&fInfo); fInfo.index = -1; } } T* operator->() const { return (T*)fInfo.ptr.attached_at; } operator T*() const { return (T*)fInfo.ptr.attached_at; } JackShmReadWritePtr1& operator=(int index) { Init(index); return *this; } void SetShmIndex(int index, const char* server_name) { Init(index, server_name); } int GetShmIndex() { return fInfo.index; } T* GetShmAddress() { return (T*)fInfo.ptr.attached_at; } }; /*! \brief Pointer on shared memory segment in the client side. */ template class JackShmReadPtr { private: jack_shm_info_t fInfo; bool fInitDone; void Init(int index, const char* server_name = JACK_DEFAULT_SERVER_NAME) { if (fInfo.index < 0 && index >= 0) { jack_log("JackShmPtrRead::Init %ld %d", index, fInfo.index); if (jack_initialize_shm(server_name) < 0) { throw std::bad_alloc(); } fInfo.index = index; if (jack_attach_lib_shm_read(&fInfo)) { throw std::bad_alloc(); } GetShmAddress()->LockMemory(); fInitDone = true; } } public: JackShmReadPtr() { fInfo.index = -1; fInitDone = false; fInfo.ptr.attached_at = NULL; } JackShmReadPtr(int index, const char* server_name) { Init(index, server_name); } ~JackShmReadPtr() { if (!fInitDone) { jack_error("JackShmReadPtr::~JackShmReadPtr - Init not done for %ld, skipping unlock", fInfo.index); return; } if (fInfo.index >= 0) { jack_log("JackShmPtrRead::~JackShmPtrRead %ld", fInfo.index); GetShmAddress()->UnlockMemory(); jack_release_lib_shm(&fInfo); fInfo.index = -1; } } T* operator->() const { return (T*)fInfo.ptr.attached_at; } operator T*() const { return (T*)fInfo.ptr.attached_at; } JackShmReadPtr& operator=(int index) { Init(index); return *this; } void SetShmIndex(int index, const char* server_name) { Init(index, server_name); } int GetShmIndex() { return fInfo.index; } T* GetShmAddress() { return (T*)fInfo.ptr.attached_at; } }; } // end of namespace #endif 1.9.12~dfsg/common/JackAudioAdapterInterface.h0000644000000000000000000001303513214314510017757 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackAudioAdapterInterface__ #define __JackAudioAdapterInterface__ #include "JackResampler.h" #include "JackFilters.h" #include namespace Jack { #ifdef JACK_MONITOR #define TABLE_MAX 100000 struct Measure { int delta; int time1; int time2; float r1; float r2; int pos1; int pos2; }; struct MeasureTable { Measure fTable[TABLE_MAX]; int fCount; MeasureTable() :fCount(0) {} void Write(int time1, int time2, float r1, float r2, int pos1, int pos2); void Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize); }; #endif /*! \brief Base class for audio adapters. */ class JackAudioAdapterInterface { protected: #ifdef JACK_MONITOR MeasureTable fTable; #endif //channels int fCaptureChannels; int fPlaybackChannels; //host parameters jack_nframes_t fHostBufferSize; jack_nframes_t fHostSampleRate; //adapted parameters jack_nframes_t fAdaptedBufferSize; jack_nframes_t fAdaptedSampleRate; //PI controler JackPIControler fPIControler; JackResampler** fCaptureRingBuffer; JackResampler** fPlaybackRingBuffer; unsigned int fQuality; unsigned int fRingbufferCurSize; jack_time_t fPullAndPushTime; bool fRunning; bool fAdaptative; void ResetRingBuffers(); void AdaptRingBufferSize(); void GrowRingBufferSize(); public: JackAudioAdapterInterface(jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE): fCaptureChannels(0), fPlaybackChannels(0), fHostBufferSize(buffer_size), fHostSampleRate(sample_rate), fAdaptedBufferSize(buffer_size), fAdaptedSampleRate(sample_rate), fPIControler(sample_rate / sample_rate, 256), fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL), fQuality(0), fRingbufferCurSize(ring_buffer_size), fPullAndPushTime(0), fRunning(false), fAdaptative(true) {} JackAudioAdapterInterface(jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate, jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE) : fCaptureChannels(0), fPlaybackChannels(0), fHostBufferSize(host_buffer_size), fHostSampleRate(host_sample_rate), fAdaptedBufferSize(adapted_buffer_size), fAdaptedSampleRate(adapted_sample_rate), fPIControler(host_sample_rate / host_sample_rate, 256), fQuality(0), fRingbufferCurSize(ring_buffer_size), fPullAndPushTime(0), fRunning(false), fAdaptative(true) {} virtual ~JackAudioAdapterInterface() {} virtual void Reset(); virtual void Create(); virtual void Destroy(); virtual int Open() { return 0; } virtual int Close() { return 0; } virtual int SetHostBufferSize(jack_nframes_t buffer_size); virtual int SetAdaptedBufferSize(jack_nframes_t buffer_size); virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetHostSampleRate(jack_nframes_t sample_rate); virtual int SetAdaptedSampleRate(jack_nframes_t sample_rate); virtual int SetSampleRate(jack_nframes_t sample_rate); void SetInputs(int inputs); void SetOutputs(int outputs); int GetInputs(); int GetOutputs(); virtual int GetInputLatency(int port_index) { return 0; } virtual int GetOutputLatency(int port_index) { return 0; } int PushAndPull(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int frames); int PullAndPush(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int frames); }; } #endif 1.9.12~dfsg/common/JackConnectionManager.h0000644000000000000000000003247613214314510017200 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackConnectionManager__ #define __JackConnectionManager__ #include "JackConstants.h" #include "JackActivationCount.h" #include "JackError.h" #include "JackCompilerDeps.h" #include #include namespace Jack { struct JackClientControl; /*! \brief Utility class. */ PRE_PACKED_STRUCTURE template class JackFixedArray { private: jack_int_t fTable[SIZE]; uint32_t fCounter; public: JackFixedArray() { Init(); } void Init() { for (int i = 0; i < SIZE; i++) fTable[i] = EMPTY; fCounter = 0; } bool AddItem(jack_int_t index) { for (int i = 0; i < SIZE; i++) { if (fTable[i] == EMPTY) { fTable[i] = index; fCounter++; return true; } } return false; } bool RemoveItem(jack_int_t index) { for (int i = 0; i < SIZE; i++) { if (fTable[i] == index) { fCounter--; // Shift all indexes if (i == SIZE - 1) { fTable[i] = EMPTY; } else { int j; for (j = i; j <= SIZE - 2 && fTable[j] != EMPTY; j++) { fTable[j] = fTable[j + 1]; } fTable[j] = EMPTY; } return true; } } return false; } jack_int_t GetItem(jack_int_t index) const { return (index < SIZE) ? fTable[index] : EMPTY; } const jack_int_t* GetItems() const { return fTable; } bool CheckItem(jack_int_t index) const { for (int i = 0; i < SIZE && fTable[i] != EMPTY; i++) { if (fTable[i] == index) return true; } return false; } uint32_t GetItemCount() const { return fCounter; } } POST_PACKED_STRUCTURE; /*! \brief Utility class. */ PRE_PACKED_STRUCTURE template class JackFixedArray1 : public JackFixedArray { private: bool fUsed; public: JackFixedArray1() { Init(); } void Init() { JackFixedArray::Init(); fUsed = false; } bool IsAvailable() { if (fUsed) { return false; } else { fUsed = true; return true; } } } POST_PACKED_STRUCTURE; /*! \brief Utility class. */ PRE_PACKED_STRUCTURE template class JackFixedMatrix { private: jack_int_t fTable[SIZE][SIZE]; public: JackFixedMatrix() {} void Init(jack_int_t index) { for (int i = 0; i < SIZE; i++) { fTable[index][i] = 0; fTable[i][index] = 0; } } const jack_int_t* GetItems(jack_int_t index) const { return fTable[index]; } jack_int_t IncItem(jack_int_t index1, jack_int_t index2) { fTable[index1][index2]++; return fTable[index1][index2]; } jack_int_t DecItem(jack_int_t index1, jack_int_t index2) { fTable[index1][index2]--; return fTable[index1][index2]; } jack_int_t GetItemCount(jack_int_t index1, jack_int_t index2) const { return fTable[index1][index2]; } void ClearItem(jack_int_t index1, jack_int_t index2) { fTable[index1][index2] = 0; } /*! \brief Get the output indexes of a given index. */ void GetOutputTable(jack_int_t index, jack_int_t* output) const { int i, j; for (i = 0; i < SIZE; i++) output[i] = EMPTY; for (i = 0, j = 0; i < SIZE; i++) { if (fTable[index][i] > 0) { output[j] = i; j++; } } } void GetOutputTable1(jack_int_t index, jack_int_t* output) const { for (int i = 0; i < SIZE; i++) { output[i] = fTable[i][index]; } } bool IsInsideTable(jack_int_t index, jack_int_t* output) const { for (int i = 0; i < SIZE && output[i] != EMPTY; i++) { if (output[i] == index) return true; } return false; } void Copy(JackFixedMatrix& copy) { for (int i = 0; i < SIZE; i++) { memcpy(copy.fTable[i], fTable[i], sizeof(jack_int_t) * SIZE); } } } POST_PACKED_STRUCTURE; /*! \brief Utility class. */ PRE_PACKED_STRUCTURE template class JackLoopFeedback { private: int fTable[SIZE][3]; /*! \brief Add a feedback connection between 2 refnum. */ bool AddConnectionAux(int ref1, int ref2) { for (int i = 0; i < SIZE; i++) { if (fTable[i][0] == EMPTY) { fTable[i][0] = ref1; fTable[i][1] = ref2; fTable[i][2] = 1; jack_log("JackLoopFeedback::AddConnectionAux ref1 = %ld ref2 = %ld", ref1, ref2); return true; } } jack_error("Feedback table is full !!\n"); return false; } /*! \brief Remove a feedback connection between 2 refnum. */ bool RemoveConnectionAux(int ref1, int ref2) { for (int i = 0; i < SIZE; i++) { if (fTable[i][0] == ref1 && fTable[i][1] == ref2) { fTable[i][0] = EMPTY; fTable[i][1] = EMPTY; fTable[i][2] = 0; jack_log("JackLoopFeedback::RemoveConnectionAux ref1 = %ld ref2 = %ld", ref1, ref2); return true; } } jack_error("Feedback connection not found\n"); return false; } int IncConnection(int index) { fTable[index][2]++; return fTable[index][2]; } int DecConnection(int index) { fTable[index][2]--; return fTable[index][2]; } public: JackLoopFeedback() { Init(); } void Init() { for (int i = 0; i < SIZE; i++) { fTable[i][0] = EMPTY; fTable[i][1] = EMPTY; fTable[i][2] = 0; } } bool IncConnection(int ref1, int ref2) { int index = GetConnectionIndex(ref1, ref2); if (index >= 0) { // Feedback connection is already added, increment counter IncConnection(index); return true; } else { return AddConnectionAux(ref1, ref2); // Add the feedback connection } } bool DecConnection(int ref1, int ref2) { int index = GetConnectionIndex(ref1, ref2); if (index >= 0) { jack_log("JackLoopFeedback::DecConnection ref1 = %ld ref2 = %ld index = %ld", ref1, ref2, index); return (DecConnection(index) == 0) ? RemoveConnectionAux(ref1, ref2) : true; } else { return false; } } /*! \brief Test if a connection between 2 refnum is a feedback connection. */ int GetConnectionIndex(int ref1, int ref2) const { for (int i = 0; i < SIZE; i++) { if (fTable[i][0] == ref1 && fTable[i][1] == ref2) return i; } return -1; } } POST_PACKED_STRUCTURE; /*! \brief For client timing measurements. */ PRE_PACKED_STRUCTURE struct JackClientTiming { jack_time_t fSignaledAt; jack_time_t fAwakeAt; jack_time_t fFinishedAt; jack_client_state_t fStatus; JackClientTiming() { Init(); } ~JackClientTiming() {} void Init() { fSignaledAt = 0; fAwakeAt = 0; fFinishedAt = 0; fStatus = NotTriggered; } } POST_PACKED_STRUCTURE; /*! \brief Connection manager.
  • The fConnection array contains the list (array line) of connected ports for a given port.
  • The fInputPort array contains the list (array line) of input connected ports for a given client.
  • The fOutputPort array contains the list (array line) of ouput connected ports for a given client.
  • The fConnectionRef array contains the number of ports connected between two clients.
  • The fInputCounter array contains the number of input clients connected to a given for activation purpose.
*/ PRE_PACKED_STRUCTURE class SERVER_EXPORT JackConnectionManager { private: JackFixedArray fConnection[PORT_NUM_MAX]; /*! Connection matrix: list of connected ports for a given port: needed to compute Mix buffer */ JackFixedArray1 fInputPort[CLIENT_NUM]; /*! Table of input port per refnum : to find a refnum for a given port */ JackFixedArray fOutputPort[CLIENT_NUM]; /*! Table of output port per refnum : to find a refnum for a given port */ JackFixedMatrix fConnectionRef; /*! Table of port connections by (refnum , refnum) */ JackActivationCount fInputCounter[CLIENT_NUM]; /*! Activation counter per refnum */ JackLoopFeedback fLoopFeedback; /*! Loop feedback connections */ bool IsLoopPathAux(int ref1, int ref2) const; public: JackConnectionManager(); ~JackConnectionManager(); // Connections management int Connect(jack_port_id_t port_src, jack_port_id_t port_dst); int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst); bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const; /*! \brief Get the connection number of a given port. */ jack_int_t Connections(jack_port_id_t port_index) const { return fConnection[port_index].GetItemCount(); } jack_port_id_t GetPort(jack_port_id_t port_index, int connection) const { assert(connection < CONNECTION_NUM_FOR_PORT); return (jack_port_id_t)fConnection[port_index].GetItem(connection); } const jack_int_t* GetConnections(jack_port_id_t port_index) const; bool IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst); bool DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst); bool IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const; bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const; void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst); void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst); // Ports management int AddInputPort(int refnum, jack_port_id_t port_index); int AddOutputPort(int refnum, jack_port_id_t port_index); int RemoveInputPort(int refnum, jack_port_id_t port_index); int RemoveOutputPort(int refnum, jack_port_id_t port_index); const jack_int_t* GetInputPorts(int refnum); const jack_int_t* GetOutputPorts(int refnum); // Client management void InitRefNum(int refnum); int GetInputRefNum(jack_port_id_t port_index) const; int GetOutputRefNum(jack_port_id_t port_index) const; // Connect/Disconnect 2 refnum "directly" bool IsDirectConnection(int ref1, int ref2) const; void DirectConnect(int ref1, int ref2); void DirectDisconnect(int ref1, int ref2); int GetActivation(int refnum) const { return fInputCounter[refnum].GetValue(); } // Graph void ResetGraph(JackClientTiming* timing); int ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing); int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec); void TopologicalSort(std::vector& sorted); } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackSession.h0000644000000000000000000000356713214314510015230 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Jack O'Quin Copyright (C) 2010 Torben Hohn This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_session_int_h__ #define __jack_session_int_h__ #include #ifdef __cplusplus extern "C" { #endif enum JackSessionEventType { JackSessionSave = 1, JackSessionSaveAndQuit = 2, JackSessionSaveTemplate = 3 }; typedef enum JackSessionEventType jack_session_event_type_t; enum JackSessionFlags { JackSessionSaveError = 0x01, JackSessionNeedTerminal = 0x02 }; typedef enum JackSessionFlags jack_session_flags_t; struct _jack_session_event { jack_session_event_type_t type; const char *session_dir; const char *client_uuid; char *command_line; jack_session_flags_t flags; uint32_t future; }; typedef struct _jack_session_event jack_session_event_t; typedef void (*JackSessionCallback)(jack_session_event_t *event, void *arg); typedef struct { const char *uuid; const char *client_name; const char *command; jack_session_flags_t flags; } jack_session_command_t; #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/common/JackChannel.h0000644000000000000000000001412013214314510015140 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackChannel__ #define __JackChannel__ #include "types.h" #include "JackSession.h" namespace Jack { class JackClientInterface; class JackClient; class JackServer; struct JackEngineControl; class JackGraphManager; namespace detail { class JackChannelTransactionInterface { public: JackChannelTransactionInterface() {} virtual ~JackChannelTransactionInterface() {} virtual int Read(void* data, int len) = 0; virtual int Write(void* data, int len) = 0; }; class JackRequestInterface { public: JackRequestInterface() {} virtual ~JackRequestInterface() {} virtual int Connect(const char* dir, const char* name, int which) = 0; virtual int Close() = 0; }; class JackClientRequestInterface : public JackChannelTransactionInterface, public JackRequestInterface { public: JackClientRequestInterface() {} virtual ~JackClientRequestInterface() {} virtual int Read(void* data, int len) { return -1; } virtual int Write(void* data, int len) { return -1; } virtual int Connect(const char* dir, const char* name, int which) { return -1; } virtual int Close() { return -1; } }; /*! \brief Inter process channel for server/client bidirectionnal communication : request and (receiving) notifications. */ class JackClientChannelInterface { public: JackClientChannelInterface() {} virtual ~JackClientChannelInterface() {} // Open the Server/Client connection virtual int Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) { return 0; } // Close the Server/Client connection virtual void Close() {} // Start listening for messages from the server virtual int Start() { return 0; } // Stop listening for messages from the server virtual void Stop() {} virtual int ServerCheck(const char* server_name) { return -1; } virtual void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open) {} virtual void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) {} virtual void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) {} virtual void ClientClose(int refnum, int* result) {} virtual void ClientActivate(int refnum, int is_real_time, int* result) {} virtual void ClientDeactivate(int refnum, int* result) {} virtual void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) {} virtual void PortUnRegister(int refnum, jack_port_id_t port_index, int* result) {} virtual void PortConnect(int refnum, const char* src, const char* dst, int* result) {} virtual void PortDisconnect(int refnum, const char* src, const char* dst, int* result) {} virtual void PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) {} virtual void PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) {} virtual void PortRename(int refnum, jack_port_id_t port, const char* name, int* result) {} virtual void SetBufferSize(jack_nframes_t buffer_size, int* result) {} virtual void SetFreewheel(int onoff, int* result) {} virtual void ComputeTotalLatencies(int* result) {} virtual void ReleaseTimebase(int refnum, int* result) {} virtual void SetTimebaseCallback(int refnum, int conditional, int* result) {} virtual void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) {} virtual void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result) {} virtual void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) {} virtual void InternalClientUnload(int refnum, int int_ref, int* status, int* result) {} virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) {} virtual void SessionReply(int refnum, int* result) {} virtual void GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result) {} virtual void GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result) {} virtual void ReserveClientName(int refnum, const char* client_name, const char *uuid, int* result) {} virtual void ClientHasSessionCallback(const char* client_name, int* result) {} virtual bool IsChannelThread() { return false; } }; } } // end of namespace #endif 1.9.12~dfsg/common/JackArgParser.cpp0000644000000000000000000001777013214314510016027 0ustar rootroot/* Copyright (C) 2006-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackDriverLoader.h" #include "JackArgParser.h" #include #include #include using namespace std; namespace Jack { // class JackArgParser *************************************************** JackArgParser::JackArgParser ( const char* arg ) { jack_log ( "JackArgParser::JackArgParser, arg_string : '%s'", arg ); fArgc = 0; //if empty string if ( strlen(arg) == 0 ) return; fArgString = string(arg); //else parse the arg string const size_t arg_len = fArgString.length(); unsigned int i = 0; size_t pos = 0; size_t start = 0; size_t copy_start = 0; size_t copy_length = 0; //we need a 'space terminated' string fArgString += " "; //first fill a vector with args do { //find the first non-space character from the actual position start = fArgString.find_first_not_of ( ' ', start ); //get the next quote or space position pos = fArgString.find_first_of ( " \"" , start ); //no more quotes or spaces, consider the end of the string if ( pos == string::npos ) pos = arg_len; //if double quote if ( fArgString[pos] == '\"' ) { //first character : copy the substring if ( pos == start ) { copy_start = start + 1; pos = fArgString.find ( '\"', ++pos ); copy_length = pos - copy_start; start = pos + 1; } //else there is someting before the quote, first copy that else { copy_start = start; copy_length = pos - copy_start; start = pos; } } //if space if ( fArgString[pos] == ' ' ) { //short option descriptor if ( ( fArgString[start] == '-' ) && ( fArgString[start + 1] != '-' ) ) { copy_start = start; copy_length = 2; start += copy_length; } //else copy all the space delimitated string else { copy_start = start; copy_length = pos - copy_start; start = pos + 1; } } //then push the substring to the args vector fArgv.push_back ( fArgString.substr ( copy_start, copy_length ) ); jack_log ( "JackArgParser::JackArgParser, add : '%s'", (*fArgv.rbegin()).c_str() ); } while ( start < arg_len ); //finally count the options for ( i = 0; i < fArgv.size(); i++ ) if ( fArgv[i].at(0) == '-' ) fArgc++; } JackArgParser::~JackArgParser() {} string JackArgParser::GetArgString() { return fArgString; } int JackArgParser::GetNumArgv() { return fArgv.size(); } int JackArgParser::GetArgc() { return fArgc; } int JackArgParser::GetArgv ( vector& argv ) { argv = fArgv; return 0; } int JackArgParser::GetArgv ( char** argv ) { //argv must be NULL if ( argv ) return -1; //else allocate and fill it argv = (char**)calloc (fArgv.size(), sizeof(char*)); if (argv == NULL) { return -1; } for ( unsigned int i = 0; i < fArgv.size(); i++ ) { argv[i] = (char*)calloc(fArgv[i].length(), sizeof(char)); fill_n ( argv[i], fArgv[i].length() + 1, 0 ); fArgv[i].copy ( argv[i], fArgv[i].length() ); } return 0; } void JackArgParser::DeleteArgv ( const char** argv ) { unsigned int i; for ( i = 0; i < fArgv.size(); i++ ) free((void*)argv[i]); free((void*)argv); } bool JackArgParser::ParseParams ( jack_driver_desc_t* desc, JSList** param_list ) { string options_list; unsigned long i = 0; unsigned int param = 0; size_t param_id = 0; JSList* params = NULL; jack_driver_param_t* intclient_param; for ( i = 0; i < desc->nparams; i++ ) options_list += desc->params[i].character; for ( param = 0; param < fArgv.size(); param++ ) { if ( fArgv[param][0] == '-' ) { //valid option if ( ( param_id = options_list.find_first_of ( fArgv[param].at(1) ) ) != string::npos ) { intclient_param = static_cast ( calloc ( 1, sizeof ( jack_driver_param_t) ) ); intclient_param->character = desc->params[param_id].character; switch ( desc->params[param_id].type ) { case JackDriverParamInt: if (param + 1 < fArgv.size()) // something to parse intclient_param->value.i = atoi ( fArgv[param + 1].c_str() ); break; case JackDriverParamUInt: if (param + 1 < fArgv.size()) // something to parse intclient_param->value.ui = strtoul ( fArgv[param + 1].c_str(), NULL, 10 ); break; case JackDriverParamChar: if (param + 1 < fArgv.size()) // something to parse intclient_param->value.c = fArgv[param + 1][0]; break; case JackDriverParamString: if (param + 1 < fArgv.size()) // something to parse fArgv[param + 1].copy ( intclient_param->value.str, min(static_cast(fArgv[param + 1].length()), JACK_DRIVER_PARAM_STRING_MAX) ); break; case JackDriverParamBool: intclient_param->value.i = true; break; } //add to the list params = jack_slist_append ( params, intclient_param ); } //invalid option else { if (fArgv[param][1] == 'h') { fprintf(stdout, "Internal client parameters:\n"); jack_print_driver_options (desc, stdout); return false; } else { jack_error ( "Invalid option '%c'", fArgv[param][1] ); } } } } assert(param_list); *param_list = params; return true; } void JackArgParser::FreeParams ( JSList* param_list ) { JSList *node_ptr = param_list; JSList *next_node_ptr; while (node_ptr) { next_node_ptr = node_ptr->next; free(node_ptr->data); free(node_ptr); node_ptr = next_node_ptr; } } } 1.9.12~dfsg/common/JackArgParser.h0000644000000000000000000000323613214314510015464 0ustar rootroot/* Copyright (C) 2006-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackArgParser__ #define __JackArgParser__ #include "jslist.h" #include "driver_interface.h" #include "JackCompilerDeps.h" #include "JackError.h" #include #include #include #include #include namespace Jack { class SERVER_EXPORT JackArgParser { private: std::string fArgString; int fArgc; std::vector fArgv; public: JackArgParser ( const char* arg ); ~JackArgParser(); std::string GetArgString(); int GetNumArgv(); int GetArgc(); int GetArgv ( std::vector& argv ); int GetArgv ( char** argv ); void DeleteArgv ( const char** argv ); bool ParseParams ( jack_driver_desc_t* desc, JSList** param_list ); void FreeParams ( JSList* param_list ); }; } #endif 1.9.12~dfsg/common/JackLoopbackDriver.cpp0000644000000000000000000000714213214314510017037 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackLoopbackDriver.h" #include "JackDriverLoader.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackError.h" #include #include namespace Jack { // When used in "slave" mode int JackLoopbackDriver::ProcessReadSync() { int res = 0; // Loopback copy for (int i = 0; i < fCaptureChannels; i++) { memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } // Resume connected clients in the graph if (ResumeRefNum() < 0) { jack_error("JackLoopbackDriver::ProcessReadSync - ResumeRefNum error"); res = -1; } return res; } int JackLoopbackDriver::ProcessWriteSync() { // Suspend on connected clients in the graph if (SuspendRefNum() < 0) { jack_error("JackLoopbackDriver::ProcessWriteSync - SuspendRefNum error"); return -1; } return 0; } int JackLoopbackDriver::ProcessReadAsync() { int res = 0; // Loopback copy for (int i = 0; i < fCaptureChannels; i++) { memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } // Resume connected clients in the graph if (ResumeRefNum() < 0) { jack_error("JackLoopbackDriver::ProcessReadAsync - ResumeRefNum error"); res = -1; } return res; } int JackLoopbackDriver::ProcessWriteAsync() { return 0; } } // end of namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("loopback", JackDriverSlave, "Loopback backend", &filler); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "channels", 'c', JackDriverParamInt, &value, NULL, "Maximum number of loopback ports", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { const JSList * node; const jack_driver_param_t * param; int channels = 2; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'c': channels = param->value.ui; break; } } Jack::JackDriverClientInterface* driver = new Jack::JackLoopbackDriver(engine, table); if (driver->Open(0, 0, 1, 1, channels, channels, false, "loopback", "loopback", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/common/JackError.h0000644000000000000000000000350713214314510014670 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame Copyright (C) 2008 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackError__ #define __JackError__ #include #include #include "JackCompilerDeps.h" #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT void jack_error(const char *fmt, ...); SERVER_EXPORT void jack_info(const char *fmt, ...); SERVER_EXPORT void jack_log(const char *fmt, ...); SERVER_EXPORT extern void (*jack_error_callback)(const char *desc); SERVER_EXPORT extern void (*jack_info_callback)(const char *desc); SERVER_EXPORT extern void default_jack_error_callback(const char *desc); SERVER_EXPORT extern void default_jack_info_callback(const char *desc); SERVER_EXPORT void silent_jack_error_callback(const char *desc); SERVER_EXPORT void silent_jack_info_callback(const char *desc); SERVER_EXPORT int set_threaded_log_function(); #define LOG_LEVEL_INFO 1 #define LOG_LEVEL_ERROR 2 void jack_log_function(int level, const char *message); typedef void (* jack_log_function_t)(int level, const char *message); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/common/JackGraphManager.h0000644000000000000000000001277213214314510016137 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackGraphManager__ #define __JackGraphManager__ #include "JackShmMem.h" #include "JackPort.h" #include "JackConstants.h" #include "JackConnectionManager.h" #include "JackAtomicState.h" #include "JackPlatformPlug.h" #include "JackSystemDeps.h" namespace Jack { /*! \brief Graph manager: contains the connection manager and the port array. */ PRE_PACKED_STRUCTURE class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState { private: unsigned int fPortMax; JackClientTiming fClientTiming[CLIENT_NUM]; JackPort fPortArray[0]; // The actual size depends of port_max, it will be dynamically computed and allocated using "placement" new void AssertPort(jack_port_id_t port_index); jack_port_id_t AllocatePortAux(int refnum, const char* port_name, const char* port_type, JackPortFlags flags); void GetConnectionsAux(JackConnectionManager* manager, const char** res, jack_port_id_t port_index); void GetPortsAux(const char** matching_ports, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags); jack_default_audio_sample_t* GetBuffer(jack_port_id_t port_index); void* GetBufferAux(JackConnectionManager* manager, jack_port_id_t port_index, jack_nframes_t frames); jack_nframes_t ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count); void RecalculateLatencyAux(jack_port_id_t port_index, jack_latency_callback_mode_t mode); public: JackGraphManager(int port_max); ~JackGraphManager() {} void SetBufferSize(jack_nframes_t buffer_size); // Ports management jack_port_id_t AllocatePort(int refnum, const char* port_name, const char* port_type, JackPortFlags flags, jack_nframes_t buffer_size); int ReleasePort(int refnum, jack_port_id_t port_index); void GetInputPorts(int refnum, jack_int_t* res); void GetOutputPorts(int refnum, jack_int_t* res); void RemoveAllPorts(int refnum); void DisconnectAllPorts(int refnum); JackPort* GetPort(jack_port_id_t index); jack_port_id_t GetPort(const char* name); int ComputeTotalLatency(jack_port_id_t port_index); int ComputeTotalLatencies(); void RecalculateLatency(jack_port_id_t port_index, jack_latency_callback_mode_t mode); int RequestMonitor(jack_port_id_t port_index, bool onoff); // Connections management int Connect(jack_port_id_t src_index, jack_port_id_t dst_index); int Disconnect(jack_port_id_t src_index, jack_port_id_t dst_index); int IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst); // RT, client int GetConnectionsNum(jack_port_id_t port_index) { JackConnectionManager* manager = ReadCurrentState(); return manager->Connections(port_index); } const char** GetConnections(jack_port_id_t port_index); void GetConnections(jack_port_id_t port_index, jack_int_t* connections); // TODO const char** GetPorts(const char* port_name_pattern, const char* type_name_pattern, unsigned long flags); int GetTwoPorts(const char* src, const char* dst, jack_port_id_t* src_index, jack_port_id_t* dst_index); int CheckPorts(jack_port_id_t port_src, jack_port_id_t port_dst); void DisconnectAllInput(jack_port_id_t port_index); void DisconnectAllOutput(jack_port_id_t port_index); int DisconnectAll(jack_port_id_t port_index); bool IsDirectConnection(int ref1, int ref2); void DirectConnect(int ref1, int ref2); void DirectDisconnect(int ref1, int ref2); void Activate(int refnum); void Deactivate(int refnum); int GetInputRefNum(jack_port_id_t port_index); int GetOutputRefNum(jack_port_id_t port_index); // Buffer management void* GetBuffer(jack_port_id_t port_index, jack_nframes_t frames); // Activation management void RunCurrentGraph(); bool RunNextGraph(); bool IsFinishedGraph(); void InitRefNum(int refnum); int ResumeRefNum(JackClientControl* control, JackSynchro* table); int SuspendRefNum(JackClientControl* control, JackSynchro* table, long usecs); void TopologicalSort(std::vector& sorted); JackClientTiming* GetClientTiming(int refnum) { return &fClientTiming[refnum]; } void Save(JackConnectionManager* dst); void Restore(JackConnectionManager* src); static JackGraphManager* Allocate(int port_max); static void Destroy(JackGraphManager* manager); } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackLibSampleRateResampler.h0000644000000000000000000000263213214314510020134 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackLibSampleRateResampler__ #define __JackLibSampleRateResampler__ #include "JackResampler.h" #include namespace Jack { /*! \brief Resampler using "libsamplerate" (http://www.mega-nerd.com/SRC/). */ class JackLibSampleRateResampler : public JackResampler { private: SRC_STATE* fResampler; public: JackLibSampleRateResampler(); JackLibSampleRateResampler(unsigned int quality); virtual ~JackLibSampleRateResampler(); unsigned int ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames); unsigned int WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames); void Reset(unsigned int new_size); }; } #endif 1.9.12~dfsg/common/JackMidiAsyncQueue.cpp0000644000000000000000000000620513214314510017015 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "JackMidiAsyncQueue.h" using Jack::JackMidiAsyncQueue; JackMidiAsyncQueue::JackMidiAsyncQueue(size_t max_bytes, size_t max_messages) { data_buffer = new jack_midi_data_t[max_bytes]; byte_ring = jack_ringbuffer_create((max_bytes * sizeof(jack_midi_data_t)) + 1); if (byte_ring) { info_ring = jack_ringbuffer_create((max_messages * INFO_SIZE) + 1); if (info_ring) { jack_ringbuffer_mlock(byte_ring); jack_ringbuffer_mlock(info_ring); this->max_bytes = max_bytes; return; } jack_ringbuffer_free(byte_ring); } delete data_buffer; throw std::bad_alloc(); } JackMidiAsyncQueue::~JackMidiAsyncQueue() { jack_ringbuffer_free(byte_ring); jack_ringbuffer_free(info_ring); delete[] data_buffer; } jack_midi_event_t * JackMidiAsyncQueue::DequeueEvent() { jack_midi_event_t *event = 0; if (jack_ringbuffer_read_space(info_ring) >= INFO_SIZE) { size_t size; event = &dequeue_event; jack_ringbuffer_read(info_ring, (char *) &(event->time), sizeof(jack_nframes_t)); jack_ringbuffer_read(info_ring, (char *) &size, sizeof(size_t)); jack_ringbuffer_read(byte_ring, (char *) data_buffer, size * sizeof(jack_midi_data_t)); event->buffer = data_buffer; event->size = size; } return event; } Jack::JackMidiWriteQueue::EnqueueResult JackMidiAsyncQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) { if (size > max_bytes) { return BUFFER_TOO_SMALL; } if (! ((jack_ringbuffer_write_space(info_ring) >= INFO_SIZE) && (jack_ringbuffer_write_space(byte_ring) >= (size * sizeof(jack_midi_data_t))))) { return BUFFER_FULL; } jack_ringbuffer_write(byte_ring, (const char *) buffer, size * sizeof(jack_midi_data_t)); jack_ringbuffer_write(info_ring, (const char *) (&time), sizeof(jack_nframes_t)); jack_ringbuffer_write(info_ring, (const char *) (&size), sizeof(size_t)); return OK; } size_t JackMidiAsyncQueue::GetAvailableSpace() { return jack_ringbuffer_write_space(info_ring) < INFO_SIZE ? 0 : max_bytes - jack_ringbuffer_read_space(byte_ring); } 1.9.12~dfsg/common/JackNotification.h0000644000000000000000000000302313214314510016216 0ustar rootroot/* Copyright (C) 2007 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackNotification__ #define __JackNotification__ namespace Jack { /*! \brief Notifications sent by the server for clients. */ enum NotificationType { kAddClient = 0, kRemoveClient = 1, kActivateClient = 2, kXRunCallback = 3, kGraphOrderCallback = 4, kBufferSizeCallback = 5, kSampleRateCallback = 6, kStartFreewheelCallback = 7, kStopFreewheelCallback = 8, kPortRegistrationOnCallback = 9, kPortRegistrationOffCallback = 10, kPortConnectCallback = 11, kPortDisconnectCallback = 12, kPortRenameCallback = 13, kRealTimeCallback = 14, kShutDownCallback = 15, kQUIT = 16, kSessionCallback = 17, kLatencyCallback = 18, kMaxNotification = 64 // To keep some room in JackClientControl fCallback table }; } // end of namespace #endif 1.9.12~dfsg/common/JackMidiDriver.h0000644000000000000000000000430513214314510015632 0ustar rootroot/* Copyright (C) 2009 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackMidiDriver__ #define __JackMidiDriver__ #include "JackDriver.h" #include "JackMidiPort.h" #include "JackLockedEngine.h" #include "ringbuffer.h" namespace Jack { /*! \brief The base class for MIDI drivers: drivers with MIDI ports. A concrete derived class will have to be defined with a real MIDI driver API, either callback based one (like CoreMIDI..) ones or blocking ones (like ALSA MIDI). */ class SERVER_EXPORT JackMidiDriver : public JackDriver { protected: JackMidiBuffer* GetInputBuffer(int port_index); JackMidiBuffer* GetOutputBuffer(int port_index); virtual int ProcessReadSync(); virtual int ProcessWriteSync(); virtual int ProcessReadAsync(); virtual int ProcessWriteAsync(); virtual void UpdateLatencies(); public: JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); virtual ~JackMidiDriver(); virtual int Open(bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int Attach(); virtual int Detach(); }; } // end of namespace #endif 1.9.12~dfsg/common/JackFilters.h0000644000000000000000000002635713214314510015217 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackFilters__ #define __JackFilters__ #ifdef __APPLE__ #include #endif #include "jack.h" #ifndef MY_TARGET_OS_IPHONE #include "JackAtomicState.h" #endif #include #include namespace Jack { #ifndef TARGET_OS_IPHONE #define MAX_SIZE 64 PRE_PACKED_STRUCTURE struct JackFilter { jack_time_t fTable[MAX_SIZE]; JackFilter() { for (int i = 0; i < MAX_SIZE; i++) { fTable[i] = 0; } } void AddValue(jack_time_t val) { memcpy(&fTable[1], &fTable[0], sizeof(jack_time_t) * (MAX_SIZE - 1)); fTable[0] = val; } jack_time_t GetVal() { jack_time_t mean = 0; for (int i = 0; i < MAX_SIZE; i++) { mean += fTable[i]; } return mean / MAX_SIZE; } } POST_PACKED_STRUCTURE; PRE_PACKED_STRUCTURE class JackDelayLockedLoop { private: jack_nframes_t fFrames; jack_time_t fCurrentWakeup; jack_time_t fCurrentCallback; jack_time_t fNextWakeUp; float fSecondOrderIntegrator; jack_nframes_t fBufferSize; jack_nframes_t fSampleRate; jack_time_t fPeriodUsecs; float fFilterCoefficient; /* set once, never altered */ bool fUpdating; public: JackDelayLockedLoop() {} JackDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate) { Init(buffer_size, sample_rate); } void Init(jack_nframes_t buffer_size, jack_nframes_t sample_rate) { fFrames = 0; fCurrentWakeup = 0; fCurrentCallback = 0; fNextWakeUp = 0; fFilterCoefficient = 0.01f; fSecondOrderIntegrator = 0.0f; fBufferSize = buffer_size; fSampleRate = sample_rate; fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize); // in microsec } void Init(jack_time_t callback_usecs) { fFrames = 0; fCurrentWakeup = 0; fSecondOrderIntegrator = 0.0f; fCurrentCallback = callback_usecs; fNextWakeUp = callback_usecs + fPeriodUsecs; } void IncFrame(jack_time_t callback_usecs) { float delta = (int64_t)callback_usecs - (int64_t)fNextWakeUp; fCurrentWakeup = fNextWakeUp; fCurrentCallback = callback_usecs; fFrames += fBufferSize; fSecondOrderIntegrator += 0.5f * fFilterCoefficient * delta; fNextWakeUp = fCurrentWakeup + fPeriodUsecs + (int64_t) floorf((fFilterCoefficient * (delta + fSecondOrderIntegrator))); } jack_nframes_t Time2Frames(jack_time_t time) { long delta = (long) rint(((double) ((long long)(time - fCurrentWakeup)) / ((long long)(fNextWakeUp - fCurrentWakeup))) * fBufferSize); return (delta < 0) ? ((fFrames > 0) ? fFrames : 1) : (fFrames + delta); } jack_time_t Frames2Time(jack_nframes_t frames) { long delta = (long) rint(((double) ((long long)(frames - fFrames)) * ((long long)(fNextWakeUp - fCurrentWakeup))) / fBufferSize); return (delta < 0) ? ((fCurrentWakeup > 0) ? fCurrentWakeup : 1) : (fCurrentWakeup + delta); } jack_nframes_t CurFrame() { return fFrames; } jack_time_t CurTime() { return fCurrentWakeup; } } POST_PACKED_STRUCTURE; PRE_PACKED_STRUCTURE class JackAtomicDelayLockedLoop : public JackAtomicState { public: JackAtomicDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate) { fState[0].Init(buffer_size, sample_rate); fState[1].Init(buffer_size, sample_rate); } void Init(jack_time_t callback_usecs) { JackDelayLockedLoop* dll = WriteNextStateStart(); dll->Init(callback_usecs); WriteNextStateStop(); TrySwitchState(); // always succeed since there is only one writer } void Init(jack_nframes_t buffer_size, jack_nframes_t sample_rate) { JackDelayLockedLoop* dll = WriteNextStateStart(); dll->Init(buffer_size, sample_rate); WriteNextStateStop(); TrySwitchState(); // always succeed since there is only one writer } void IncFrame(jack_time_t callback_usecs) { JackDelayLockedLoop* dll = WriteNextStateStart(); dll->IncFrame(callback_usecs); WriteNextStateStop(); TrySwitchState(); // always succeed since there is only one writer } jack_nframes_t Time2Frames(jack_time_t time) { UInt16 next_index = GetCurrentIndex(); UInt16 cur_index; jack_nframes_t res; do { cur_index = next_index; res = ReadCurrentState()->Time2Frames(time); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read return res; } jack_time_t Frames2Time(jack_nframes_t frames) { UInt16 next_index = GetCurrentIndex(); UInt16 cur_index; jack_time_t res; do { cur_index = next_index; res = ReadCurrentState()->Frames2Time(frames); next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read return res; } } POST_PACKED_STRUCTURE; #endif /* Torben Hohn PI controler from JACK1 */ struct JackPIControler { double resample_mean; double static_resample_factor; double* offset_array; double* window_array; int offset_differential_index; double offset_integral; double catch_factor; double catch_factor2; double pclamp; double controlquant; int smooth_size; double hann(double x) { return 0.5 * (1.0 - cos(2 * M_PI * x)); } JackPIControler(double resample_factor, int fir_size) { resample_mean = resample_factor; static_resample_factor = resample_factor; offset_array = new double[fir_size]; window_array = new double[fir_size]; offset_differential_index = 0; offset_integral = 0.0; smooth_size = fir_size; for (int i = 0; i < fir_size; i++) { offset_array[i] = 0.0; window_array[i] = hann(double(i) / (double(fir_size) - 1.0)); } // These values could be configurable catch_factor = 100000; catch_factor2 = 10000; pclamp = 15.0; controlquant = 10000.0; } ~JackPIControler() { delete[] offset_array; delete[] window_array; } void Init(double resample_factor) { resample_mean = resample_factor; static_resample_factor = resample_factor; } /* double GetRatio(int fill_level) { double offset = fill_level; // Save offset. offset_array[(offset_differential_index++) % smooth_size] = offset; // Build the mean of the windowed offset array basically fir lowpassing. double smooth_offset = 0.0; for (int i = 0; i < smooth_size; i++) { smooth_offset += offset_array[(i + offset_differential_index - 1) % smooth_size] * window_array[i]; } smooth_offset /= double(smooth_size); // This is the integral of the smoothed_offset offset_integral += smooth_offset; // Clamp offset : the smooth offset still contains unwanted noise which would go straigth onto the resample coeff. // It only used in the P component and the I component is used for the fine tuning anyways. if (fabs(smooth_offset) < pclamp) smooth_offset = 0.0; // Ok, now this is the PI controller. // u(t) = K * (e(t) + 1/T \int e(t') dt') // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T double current_resample_factor = static_resample_factor - smooth_offset / catch_factor - offset_integral / catch_factor / catch_factor2; // Now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt. current_resample_factor = floor((current_resample_factor - resample_mean) * controlquant + 0.5) / controlquant + resample_mean; // Calculate resample_mean so we can init ourselves to saner values. resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; return current_resample_factor; } */ double GetRatio(int error) { double smooth_offset = error; // This is the integral of the smoothed_offset offset_integral += smooth_offset; // Ok, now this is the PI controller. // u(t) = K * (e(t) + 1/T \int e(t') dt') // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T return static_resample_factor - smooth_offset/catch_factor - offset_integral/catch_factor/catch_factor2; } void OurOfBounds() { int i; // Set the resample_rate... we need to adjust the offset integral, to do this. // first look at the PI controller, this code is just a special case, which should never execute once // everything is swung in. offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; // Also clear the array. we are beginning a new control cycle. for (i = 0; i < smooth_size; i++) { offset_array[i] = 0.0; } } }; } #endif 1.9.12~dfsg/common/JackMidiReadQueue.cpp0000644000000000000000000000154013214314510016610 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMidiReadQueue.h" using Jack::JackMidiReadQueue; JackMidiReadQueue::~JackMidiReadQueue() { // Empty } 1.9.12~dfsg/common/JackNetOneDriver.h0000644000000000000000000000717113214314510016144 0ustar rootroot/* Copyright (C) 2008-2011 Torben Horn This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackNetDriver__ #define __JackNetDriver__ #include "JackTimedDriver.h" #include "netjack.h" #include "netjack_packet.h" namespace Jack { /** \Brief This class describes the Net Backend */ class JackNetOneDriver : public JackWaiterDriver { private: netjack_driver_state_t netj; void render_payload_to_jack_ports_float(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); void render_jack_ports_to_payload_float(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); #if HAVE_CELT void render_payload_to_jack_ports_celt(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); void render_jack_ports_to_payload_celt(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); #endif #if HAVE_OPUS void render_payload_to_jack_ports_opus(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); void render_jack_ports_to_payload_opus(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); #endif void render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats); public: JackNetOneDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, int sample_rate, int period_size, int resample_factor, const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val); virtual ~JackNetOneDriver(); int Close(); int Attach(); int Detach(); int Read(); int Write(); bool Initialize(); int AllocPorts(); void FreePorts(); // BufferSize can't be changed bool IsFixedBufferSize() { return true; } int SetBufferSize(jack_nframes_t buffer_size) { return -1; } int SetSampleRate(jack_nframes_t sample_rate) { return -1; } }; } #endif 1.9.12~dfsg/common/JackLibGlobals.h0000644000000000000000000000730713214314510015613 0ustar rootroot/* Copyright (C) 2005 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackLibGlobals__ #define __JackLibGlobals__ #include "JackShmMem.h" #include "JackEngineControl.h" #include "JackGlobals.h" #include "JackPlatformPlug.h" #include "JackGraphManager.h" #include "JackMessageBuffer.h" #include "JackTime.h" #include "JackClient.h" #include "JackError.h" #include #include #ifdef WIN32 #ifdef __MINGW32__ #include typedef _sigset_t sigset_t; #else typedef HANDLE sigset_t; #endif #endif namespace Jack { class JackClient; /*! \brief Global library static structure: singleton kind of pattern. */ struct JackLibGlobals { JackShmReadWritePtr fGraphManager; /*! Shared memory Port manager */ JackShmReadWritePtr fEngineControl; /*! Shared engine control */ // transport engine has to be writable JackSynchro fSynchroTable[CLIENT_NUM]; /*! Shared synchro table */ sigset_t fProcessSignals; static int fClientCount; static JackLibGlobals* fGlobals; JackLibGlobals() { jack_log("JackLibGlobals"); if (!JackMessageBuffer::Create()) { jack_error("Cannot create message buffer"); } fGraphManager = -1; fEngineControl = -1; // Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. #ifdef WIN32 // TODO #else sigset_t signals; sigemptyset(&signals); sigaddset(&signals, SIGPIPE); sigprocmask(SIG_BLOCK, &signals, &fProcessSignals); #endif } ~JackLibGlobals() { jack_log("~JackLibGlobals"); for (int i = 0; i < CLIENT_NUM; i++) { fSynchroTable[i].Disconnect(); } JackMessageBuffer::Destroy(); // Restore old signal mask #ifdef WIN32 // TODO #else sigprocmask(SIG_BLOCK, &fProcessSignals, 0); #endif } static void Init() { if (!JackGlobals::fServerRunning && fClientCount > 0) { // Cleanup remaining clients jack_error("Jack server was closed but clients are still allocated, cleanup..."); for (int i = 0; i < CLIENT_NUM; i++) { JackClient* client = JackGlobals::fClientTable[i]; if (client) { jack_error("Cleanup client ref = %d", i); client->Close(); delete client; } } // Cleanup global context fClientCount = 0; delete fGlobals; fGlobals = NULL; } if (fClientCount++ == 0 && !fGlobals) { jack_log("JackLibGlobals Init %x", fGlobals); InitTime(); fGlobals = new JackLibGlobals(); } } static void Destroy() { if (--fClientCount == 0 && fGlobals) { jack_log("JackLibGlobals Destroy %x", fGlobals); EndTime(); delete fGlobals; fGlobals = NULL; } } }; } // end of namespace #endif 1.9.12~dfsg/common/driver_interface.h0000644000000000000000000001623513214314510016323 0ustar rootroot/* Copyright (C) 2003 Bob Ham Copyright (C) 2008 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_driver_interface_h__ #define __jack_driver_interface_h__ #ifdef __cplusplus extern "C" { #endif #include #include "jslist.h" #include "JackCompilerDeps.h" #include "JackSystemDeps.h" #define JACK_DRIVER_NAME_MAX 15 #define JACK_DRIVER_PARAM_NAME_MAX 15 #define JACK_DRIVER_PARAM_STRING_MAX 127 #define JACK_DRIVER_PARAM_DESC 255 #define JACK_PATH_MAX 511 #define JACK_CONSTRAINT_FLAG_RANGE ((uint32_t)1) /**< if set, constraint is a range (min-max) */ #define JACK_CONSTRAINT_FLAG_STRICT ((uint32_t)2) /**< if set, constraint is strict, i.e. supplying non-matching value will not work */ #define JACK_CONSTRAINT_FLAG_FAKE_VALUE ((uint32_t)4) /**< if set, values have no user meaningful meaning */ /** Driver parameter types */ typedef enum { JackDriverParamInt = 1, JackDriverParamUInt, JackDriverParamChar, JackDriverParamString, JackDriverParamBool } jack_driver_param_type_t; /** Driver types */ typedef enum { JackDriverMaster = 1, JackDriverSlave, JackDriverNone, } jack_driver_type_t; /** Driver parameter value */ typedef union { uint32_t ui; int32_t i; char c; char str[JACK_DRIVER_PARAM_STRING_MAX + 1]; } jack_driver_param_value_t; typedef struct { jack_driver_param_value_t value; char short_desc[64]; /**< A short (~30 chars) description for the user */ } jack_driver_param_value_enum_t; struct jack_constraint_enum_uint32_descriptor { uint32_t value; const char * short_desc; }; struct jack_constraint_enum_sint32_descriptor { int32_t value; const char * short_desc; }; struct jack_constraint_enum_char_descriptor { char value; const char * short_desc; }; struct jack_constraint_enum_str_descriptor { const char * value; const char * short_desc; }; typedef struct { uint32_t flags; /**< JACK_CONSTRAINT_FLAG_XXX */ union { struct { jack_driver_param_value_t min; jack_driver_param_value_t max; } range; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is set */ struct { uint32_t count; jack_driver_param_value_enum_t * possible_values_array; } enumeration; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is not set */ } constraint; } jack_driver_param_constraint_desc_t; /** A driver parameter descriptor */ typedef struct { char name[JACK_DRIVER_NAME_MAX + 1]; /**< The parameter's name */ char character; /**< The parameter's character (for getopt, etc) */ jack_driver_param_type_t type; /**< The parameter's type */ jack_driver_param_value_t value; /**< The parameter's (default) value */ jack_driver_param_constraint_desc_t * constraint; /**< Pointer to parameter constraint descriptor. NULL if there is no constraint */ char short_desc[64]; /**< A short (~30 chars) description for the user */ char long_desc[1024]; /**< A longer description for the user */ } jack_driver_param_desc_t; /** A driver parameter */ typedef struct { char character; jack_driver_param_value_t value; } jack_driver_param_t; /** A struct for describing a jack driver */ typedef struct { char name[JACK_DRIVER_NAME_MAX + 1]; /**< The driver's canonical name */ jack_driver_type_t type; /**< The driver's type */ char desc[JACK_DRIVER_PARAM_DESC + 1]; /**< The driver's extended description */ char file[JACK_PATH_MAX + 1]; /**< The filename of the driver's shared object file */ uint32_t nparams; /**< The number of parameters the driver has */ jack_driver_param_desc_t * params; /**< An array of parameter descriptors */ } jack_driver_desc_t; typedef struct { uint32_t size; /* size of the param array, in elements */ } jack_driver_desc_filler_t; int jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr); // To be used by drivers SERVER_EXPORT jack_driver_desc_t * /* Newly allocated driver descriptor, NULL on failure */ jack_driver_descriptor_construct( const char * name, /* Driver name */ jack_driver_type_t type, /* Driver type */ const char * description, /* Driver description */ jack_driver_desc_filler_t * filler); /* Pointer to stack var to be supplied to jack_driver_descriptor_add_parameter() as well. Can be NULL for drivers that have no parameters. */ SERVER_EXPORT int /* 0 on failure */ jack_driver_descriptor_add_parameter( jack_driver_desc_t * driver_descr, /* Pointer to driver descriptor as returned by jack_driver_descriptor_construct() */ jack_driver_desc_filler_t * filler, /* Pointer to the stack var that was supplied to jack_driver_descriptor_add_parameter(). */ const char * name, /* Parameter's name */ char character, /* Parameter's character (for getopt, etc) */ jack_driver_param_type_t type, /* The parameter's type */ const jack_driver_param_value_t * value_ptr, /* Pointer to parameter's (default) value */ jack_driver_param_constraint_desc_t * constraint, /* Pointer to parameter constraint descriptor. NULL if there is no constraint */ const char * short_desc, /* A short (~30 chars) description for the user */ const char * long_desc); /* A longer description for the user, if NULL short_desc will be used */ SERVER_EXPORT int jack_constraint_add_enum( jack_driver_param_constraint_desc_t ** constraint_ptr_ptr, uint32_t * array_size_ptr, jack_driver_param_value_t * value_ptr, const char * short_desc); SERVER_EXPORT void jack_constraint_free(jack_driver_param_constraint_desc_t * constraint_ptr); #define JACK_CONSTRAINT_COMPOSE_ENUM(type) \ SERVER_EXPORT \ jack_driver_param_constraint_desc_t * \ jack_constraint_compose_enum_ ## type( \ uint32_t flags, \ struct jack_constraint_enum_ ## type ## _descriptor * descr_array_ptr) JACK_CONSTRAINT_COMPOSE_ENUM(uint32); JACK_CONSTRAINT_COMPOSE_ENUM(sint32); JACK_CONSTRAINT_COMPOSE_ENUM(char); JACK_CONSTRAINT_COMPOSE_ENUM(str); typedef jack_driver_desc_t * (*JackDriverDescFunction) (); #ifdef __cplusplus } #endif #endif /* __jack_driver_interface_h__ */ 1.9.12~dfsg/common/JackAtomic.h0000644000000000000000000000224613214314510015012 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAtomic__ #define __JackAtomic__ #include "JackTypes.h" #include "JackAtomic_os.h" static inline long INC_ATOMIC(volatile SInt32* val) { SInt32 actual; do { actual = *val; } while (!CAS(actual, actual + 1, val)); return actual; } static inline long DEC_ATOMIC(volatile SInt32* val) { SInt32 actual; do { actual = *val; } while (!CAS(actual, actual - 1, val)); return actual; } #endif 1.9.12~dfsg/common/JackFreewheelDriver.cpp0000644000000000000000000000527213214314510017215 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackFreewheelDriver.h" #include "JackEngineControl.h" #include "JackLockedEngine.h" namespace Jack { // When used in "master" mode int JackFreewheelDriver::Process() { jack_log("JackFreewheelDriver::Process master %lld", fEngineControl->fTimeOutUsecs); JackDriver::CycleTakeBeginTime(); if (fEngine->Process(fBeginDateUst, fEndDateUst)) { // Resume connected clients in the graph if (ResumeRefNum() < 0) { jack_error("JackFreewheelDriver::Process: ResumeRefNum error"); } // Special "SuspendRefNum" with longer timeout if (SuspendRefNum() < 0) { // Wait for all clients to finish for FREEWHEEL_DRIVER_TIMEOUT sec jack_error("JackFreewheelDriver::Process: SuspendRefNum error"); } } else { // Graph not finished: do not activate it jack_error("JackFreewheelDriver::Process: Process error"); } return 0; } // When used in "slave" mode int JackFreewheelDriver::ProcessReadSync() { // Resume connected clients in the graph if (ResumeRefNum() < 0) { // Signal all clients jack_error("JackFreewheelDriver::ProcessReadSync: ResumeRefNum error"); return -1; } return 0; } int JackFreewheelDriver::ProcessWriteSync() { // Generic "SuspendRefNum" here if (JackDriver::SuspendRefNum() < 0) { jack_error("JackFreewheelDriver::ProcessSync: SuspendRefNum error"); return -1; } return 0; } int JackFreewheelDriver::ProcessReadAsync() { // Resume connected clients in the graph if (ResumeRefNum() < 0) { // Signal all clients jack_error("JackFreewheelDriver::ProcessReadAsync: ResumeRefNum error"); return -1; } return 0; } int JackFreewheelDriver::ProcessWriteAsync() { return 0; } int JackFreewheelDriver::SuspendRefNum() { return fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, FREEWHEEL_DRIVER_TIMEOUT * 1000000); } } // end of namespace 1.9.12~dfsg/common/shm.c0000644000000000000000000007732413214314510013600 0ustar rootroot/* This module provides a set of abstract shared memory interfaces * with support using both System V and POSIX shared memory * implementations. The code is divided into three sections: * * - common (interface-independent) code * - POSIX implementation * - System V implementation * - Windows implementation * * The implementation used is determined by whether USE_POSIX_SHM was * set in the ./configure step. */ /* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2005-2012 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackConstants.h" #ifdef WIN32 #include #include #else #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "promiscuous.h" #endif #include "shm.h" #include "JackError.h" static int GetUID() { #ifdef WIN32 return _getpid(); //#error "No getuid function available" #else return getuid(); #endif } static int GetPID() { #ifdef WIN32 return _getpid(); #else return getpid(); #endif } #ifdef USE_POSIX_SHM static jack_shmtype_t jack_shmtype = shm_POSIX; #elif WIN32 static jack_shmtype_t jack_shmtype = shm_WIN32; #else static jack_shmtype_t jack_shmtype = shm_SYSV; #endif /* interface-dependent forward declarations */ static int jack_access_registry (jack_shm_info_t *ri); static int jack_create_registry (jack_shm_info_t *ri); static void jack_remove_shm (jack_shm_id_t *id); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * common interface-independent section * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* The JACK SHM registry is a chunk of memory for keeping track of the * shared memory used by each active JACK server. This allows the * server to clean up shared memory when it exits. To avoid memory * leakage due to kill -9, crashes or debugger-driven exits, this * cleanup is also done when a new instance of that server starts. */ /* per-process global data for the SHM interfaces */ static jack_shm_id_t registry_id; /* SHM id for the registry */ #ifdef WIN32 static jack_shm_info_t registry_info = {/* SHM info for the registry */ JACK_SHM_NULL_INDEX, NULL }; #else static jack_shm_info_t registry_info = { /* SHM info for the registry */ .index = JACK_SHM_NULL_INDEX, .ptr.attached_at = MAP_FAILED }; #endif /* pointers to registry header and array */ static jack_shm_header_t *jack_shm_header = NULL; static jack_shm_registry_t *jack_shm_registry = NULL; static char jack_shm_server_prefix[JACK_SERVER_NAME_SIZE+1] = ""; /* jack_shm_lock_registry() serializes updates to the shared memory * segment JACK uses to keep track of the SHM segments allocated to * all its processes, including multiple servers. * * This is not a high-contention lock, but it does need to work across * multiple processes. High transaction rates and realtime safety are * not required. Any solution needs to at least be portable to POSIX * and POSIX-like systems. * * We must be particularly careful to ensure that the lock be released * if the owning process terminates abnormally. Otherwise, a segfault * or kill -9 at the wrong moment could prevent JACK from ever running * again on that machine until after a reboot. */ #define JACK_SEMAPHORE_KEY 0x282929 #ifndef USE_POSIX_SHM #define JACK_SHM_REGISTRY_KEY JACK_SEMAPHORE_KEY #endif static int semid = -1; #ifdef WIN32 #include #include static BOOL check_process_running(DWORD process_id) { DWORD aProcesses[2048], cbNeeded, cProcesses; unsigned int i; // Enumerate all processes if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) { return FALSE; } // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); for (i = 0; i < cProcesses; i++) { if (aProcesses[i] == process_id) { // Process process_id is running... return TRUE; } } return FALSE; } static int semaphore_init () {return 0;} static int semaphore_add (int value) {return 0;} #else /* all semaphore errors are fatal -- issue message, but do not return */ static void semaphore_error (char *msg) { jack_error ("JACK semaphore error: %s (%s)", msg, strerror (errno)); } static int semaphore_init () { key_t semkey = JACK_SEMAPHORE_KEY; struct sembuf sbuf; int create_flags = IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* Get semaphore ID associated with this key. */ if ((semid = semget(semkey, 0, 0)) == -1) { /* Semaphore does not exist - Create. */ if ((semid = semget(semkey, 1, create_flags)) != -1) { /* Initialize the semaphore, allow one owner. */ sbuf.sem_num = 0; sbuf.sem_op = 1; sbuf.sem_flg = 0; if (semop(semid, &sbuf, 1) == -1) { semaphore_error ("semop"); return -1; } } else if (errno == EEXIST) { if ((semid = semget(semkey, 0, 0)) == -1) { semaphore_error ("semget"); return -1; } } else { semaphore_error ("semget creation"); return -1; } } return 0; } static inline int semaphore_add (int value) { struct sembuf sbuf; sbuf.sem_num = 0; sbuf.sem_op = value; sbuf.sem_flg = SEM_UNDO; if (semop(semid, &sbuf, 1) == -1) { semaphore_error ("semop"); return -1; } return 0; } #endif static int jack_shm_lock_registry (void) { if (semid == -1) { if (semaphore_init () < 0) return -1; } return semaphore_add (-1); } static void jack_shm_unlock_registry (void) { semaphore_add (1); } static void jack_shm_init_registry () { /* registry must be locked */ int i; memset (jack_shm_header, 0, JACK_SHM_REGISTRY_SIZE); jack_shm_header->magic = JACK_SHM_MAGIC; //jack_shm_header->protocol = JACK_PROTOCOL_VERSION; jack_shm_header->type = jack_shmtype; jack_shm_header->size = JACK_SHM_REGISTRY_SIZE; jack_shm_header->hdr_len = sizeof (jack_shm_header_t); jack_shm_header->entry_len = sizeof (jack_shm_registry_t); for (i = 0; i < MAX_SHM_ID; ++i) { jack_shm_registry[i].index = i; } } static int jack_shm_validate_registry () { /* registry must be locked */ if ((jack_shm_header->magic == JACK_SHM_MAGIC) //&& (jack_shm_header->protocol == JACK_PROTOCOL_VERSION) && (jack_shm_header->type == jack_shmtype) && (jack_shm_header->size == JACK_SHM_REGISTRY_SIZE) && (jack_shm_header->hdr_len == sizeof (jack_shm_header_t)) && (jack_shm_header->entry_len == sizeof (jack_shm_registry_t))) { return 0; /* registry OK */ } return -1; } /* set a unique per-user, per-server shm prefix string * * According to the POSIX standard: * * "The name argument conforms to the construction rules for a * pathname. If name begins with the slash character, then processes * calling shm_open() with the same value of name refer to the same * shared memory object, as long as that name has not been * removed. If name does not begin with the slash character, the * effect is implementation-defined. The interpretation of slash * characters other than the leading slash character in name is * implementation-defined." * * Since the Linux implementation does not allow slashes *within* the * name, in the interest of portability we use colons instead. */ static void jack_set_server_prefix (const char *server_name) { #ifdef WIN32 char buffer[UNLEN+1]={0}; DWORD len = UNLEN+1; GetUserName(buffer, &len); snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), "jack-%s:%s:", buffer, server_name); #else snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), "jack-%d:%s:", GetUID(), server_name); #endif } /* gain server addressability to shared memory registration segment * * returns: 0 if successful */ static int jack_server_initialize_shm (int new_registry) { int rc; if (jack_shm_header) return 0; /* already initialized */ if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } rc = jack_access_registry (®istry_info); if (new_registry) { jack_remove_shm (®istry_id); rc = ENOENT; } switch (rc) { case ENOENT: /* registry does not exist */ rc = jack_create_registry (®istry_info); break; case 0: /* existing registry */ if (jack_shm_validate_registry () == 0) break; /* else it was invalid, so fall through */ case EINVAL: /* bad registry */ /* Apparently, this registry was created by an older * JACK version. Delete it so we can try again. */ jack_release_shm (®istry_info); jack_remove_shm (®istry_id); if ((rc = jack_create_registry (®istry_info)) != 0) { jack_error ("incompatible shm registry (%s)", strerror (errno)); #ifndef USE_POSIX_SHM jack_error ("to delete, use `ipcrm -M 0x%0.8x'", JACK_SHM_REGISTRY_KEY); #endif } break; default: /* failure return code */ break; } jack_shm_unlock_registry (); return rc; } /* gain client addressability to shared memory registration segment * * NOTE: this function is no longer used for server initialization, * instead it calls jack_register_server(). * * returns: 0 if successful */ int jack_initialize_shm (const char *server_name) { int rc; if (jack_shm_header) return 0; /* already initialized */ jack_set_server_prefix (server_name); if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } if ((rc = jack_access_registry (®istry_info)) == 0) { if ((rc = jack_shm_validate_registry ()) != 0) { jack_error ("Incompatible shm registry, " "are jackd and libjack in sync?"); } } jack_shm_unlock_registry (); return rc; } char* jack_shm_addr (jack_shm_info_t* si) { return (char*)si->ptr.attached_at; } void jack_destroy_shm (jack_shm_info_t* si) { /* must NOT have the registry locked */ if (si->index == JACK_SHM_NULL_INDEX) return; /* segment not allocated */ jack_remove_shm (&jack_shm_registry[si->index].id); jack_release_shm_info (si->index); } jack_shm_registry_t * jack_get_free_shm_info () { /* registry must be locked */ jack_shm_registry_t* si = NULL; int i; for (i = 0; i < MAX_SHM_ID; ++i) { if (jack_shm_registry[i].size == 0) { break; } } if (i < MAX_SHM_ID) { si = &jack_shm_registry[i]; } return si; } static void jack_release_shm_entry (jack_shm_registry_index_t index) { /* the registry must be locked */ jack_shm_registry[index].size = 0; jack_shm_registry[index].allocator = 0; memset (&jack_shm_registry[index].id, 0, sizeof (jack_shm_registry[index].id)); } int jack_release_shm_info (jack_shm_registry_index_t index) { /* must NOT have the registry locked */ if (jack_shm_registry[index].allocator == GetPID()) { if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } jack_release_shm_entry (index); jack_shm_unlock_registry (); } return 0; } /* Claim server_name for this process. * * returns 0 if successful * EEXIST if server_name was already active for this user * ENOSPC if server registration limit reached * ENOMEM if unable to access shared memory registry */ int jack_register_server (const char *server_name, int new_registry) { int i, res = 0; jack_set_server_prefix (server_name); if (jack_server_initialize_shm (new_registry)) return ENOMEM; if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } /* See if server_name already registered. Since server names * are per-user, we register the unique server prefix string. */ for (i = 0; i < MAX_SERVERS; i++) { if (strncmp (jack_shm_header->server[i].name, jack_shm_server_prefix, JACK_SERVER_NAME_SIZE) != 0) continue; /* no match */ if (jack_shm_header->server[i].pid == GetPID()){ res = 0; /* it's me */ goto unlock; } /* see if server still exists */ #ifdef WIN32 if (check_process_running(jack_shm_header->server[i].pid)) { res = EEXIST; /* other server running */ goto unlock; } #else if (kill (jack_shm_header->server[i].pid, 0) == 0) { res = EEXIST; /* other server running */ goto unlock; } #endif /* it's gone, reclaim this entry */ memset (&jack_shm_header->server[i], 0, sizeof (jack_shm_server_t)); } /* find a free entry */ for (i = 0; i < MAX_SERVERS; i++) { if (jack_shm_header->server[i].pid == 0) break; } if (i >= MAX_SERVERS){ res = ENOSPC; /* out of space */ goto unlock; } /* claim it */ jack_shm_header->server[i].pid = GetPID(); strncpy (jack_shm_header->server[i].name, jack_shm_server_prefix, JACK_SERVER_NAME_SIZE); unlock: jack_shm_unlock_registry (); return res; } /* release server_name registration */ int jack_unregister_server (const char *server_name /* unused */) { int i; if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } for (i = 0; i < MAX_SERVERS; i++) { if (jack_shm_header->server[i].pid == GetPID()) { memset (&jack_shm_header->server[i], 0, sizeof (jack_shm_server_t)); } } jack_shm_unlock_registry (); return 0; } /* called for server startup and termination */ int jack_cleanup_shm () { int i; int destroy; jack_shm_info_t copy; if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } for (i = 0; i < MAX_SHM_ID; i++) { jack_shm_registry_t* r; r = &jack_shm_registry[i]; memcpy (©, r, sizeof (jack_shm_info_t)); destroy = FALSE; /* ignore unused entries */ if (r->allocator == 0) continue; /* is this my shm segment? */ if (r->allocator == GetPID()) { /* allocated by this process, so unattach and destroy. */ jack_release_shm (©); destroy = TRUE; } else { /* see if allocator still exists */ #ifdef WIN32 //jack_info("TODO: kill API not available !!"); #else if (kill (r->allocator, 0)) { if (errno == ESRCH) { /* allocator no longer exists, * so destroy */ destroy = TRUE; } } #endif } if (destroy) { int index = copy.index; if ((index >= 0) && (index < MAX_SHM_ID)) { jack_remove_shm (&jack_shm_registry[index].id); jack_release_shm_entry (index); } r->size = 0; r->allocator = 0; } } jack_shm_unlock_registry (); return TRUE; } /* resize a shared memory segment * * There is no way to resize a System V shm segment. Resizing is * possible with POSIX shm, but not with the non-conformant Mac OS X * implementation. Since POSIX shm is mainly used on that platform, * it's simpler to treat them both the same. * * So, we always resize by deleting and reallocating. This is * tricky, because the old segment will not disappear until * all the clients have released it. We only do what we can * from here. * * This is not done under a single lock. I don't even want to think * about all the things that could possibly go wrong if multple * processes tried to resize the same segment concurrently. That * probably doesn't happen. */ int jack_resize_shm (jack_shm_info_t* si, jack_shmsize_t size) { jack_shm_id_t id; /* The underlying type of `id' differs for SYSV and POSIX */ memcpy (&id, &jack_shm_registry[si->index].id, sizeof (id)); jack_release_shm (si); jack_destroy_shm (si); if (jack_shmalloc ((char *) id, size, si)) { return -1; } return jack_attach_shm (si); } int jack_attach_lib_shm (jack_shm_info_t* si) { int res = jack_attach_shm(si); if (res == 0) si->size = jack_shm_registry[si->index].size; // Keep size in si struct return res; } int jack_attach_lib_shm_read (jack_shm_info_t* si) { int res = jack_attach_shm_read(si); if (res == 0) si->size = jack_shm_registry[si->index].size; // Keep size in si struct return res; } #ifdef USE_POSIX_SHM /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * POSIX interface-dependent functions * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* gain addressability to existing SHM registry segment * * sets up global registry pointers, if successful * * returns: 0 if existing registry accessed successfully * ENOENT if registry does not exist * EINVAL if registry exists, but has the wrong size */ static int jack_access_registry (jack_shm_info_t *ri) { /* registry must be locked */ int shm_fd; strncpy (registry_id, "/jack-shm-registry", sizeof (registry_id)); /* try to open an existing segment */ if ((shm_fd = shm_open (registry_id, O_RDWR, 0666)) < 0) { int rc = errno; if (errno != ENOENT) { jack_error ("Cannot open existing shm registry segment" " (%s)", strerror (errno)); } close (shm_fd); return rc; } if ((ri->ptr.attached_at = mmap (0, JACK_SHM_REGISTRY_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { jack_error ("Cannot mmap shm registry segment (%s)", strerror (errno)); close (shm_fd); return EINVAL; } /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); close (shm_fd); return 0; } /* create a new SHM registry segment * * sets up global registry pointers, if successful * * returns: 0 if registry created successfully * nonzero error code if unable to allocate a new registry */ static int jack_create_registry (jack_shm_info_t *ri) { /* registry must be locked */ int shm_fd; strncpy (registry_id, "/jack-shm-registry", sizeof (registry_id)); if ((shm_fd = shm_open (registry_id, O_RDWR|O_CREAT, 0666)) < 0) { int rc = errno; jack_error ("Cannot create shm registry segment (%s)", strerror (errno)); return rc; } /* Previous shm_open result depends of the actual value of umask, force correct file permisssion here */ if (fchmod(shm_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0) { jack_log("Cannot chmod jack-shm-registry (%s) %d %d", strerror (errno)); } /* Set the desired segment size. NOTE: the non-conformant Mac * OS X POSIX shm only allows ftruncate() on segment creation. */ if (ftruncate (shm_fd, JACK_SHM_REGISTRY_SIZE) < 0) { int rc = errno; jack_error ("Cannot set registry size (%s)", strerror (errno)); jack_remove_shm (®istry_id); close (shm_fd); return rc; } if ((ri->ptr.attached_at = mmap (0, JACK_SHM_REGISTRY_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { jack_error ("Cannot mmap shm registry segment (%s)", strerror (errno)); jack_remove_shm (®istry_id); close (shm_fd); return EINVAL; } /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); /* initialize registry contents */ jack_shm_init_registry (); close (shm_fd); return 0; } static void jack_remove_shm (jack_shm_id_t *id) { /* registry may or may not be locked */ shm_unlink ((char *) id); } void jack_release_shm (jack_shm_info_t* si) { /* registry may or may not be locked */ if (si->ptr.attached_at != MAP_FAILED) { munmap (si->ptr.attached_at, jack_shm_registry[si->index].size); } } void jack_release_lib_shm (jack_shm_info_t* si) { /* registry may or may not be locked */ if (si->ptr.attached_at != MAP_FAILED) { munmap (si->ptr.attached_at, si->size); } } /* allocate a POSIX shared memory segment */ int jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) { jack_shm_registry_t* registry; int shm_fd; int rc = -1; char name[SHM_NAME_MAX+1]; const char* promiscuous; if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } if ((registry = jack_get_free_shm_info ()) == NULL) { jack_error ("shm registry full"); goto unlock; } /* On Mac OS X, the maximum length of a shared memory segment * name is SHM_NAME_MAX (instead of NAME_MAX or PATH_MAX as * defined by the standard). Unfortunately, Apple sets this * value so small (about 31 bytes) that it is useless for * actual names. So, we construct a short name from the * registry index for uniqueness and ignore the shm_name * parameter. Bah! */ snprintf (name, sizeof (name), "/jack-%d-%d", GetUID(), registry->index); if (strlen (name) >= sizeof (registry->id)) { jack_error ("shm segment name too long %s", name); goto unlock; } if ((shm_fd = shm_open (name, O_RDWR|O_CREAT, 0666)) < 0) { jack_error ("Cannot create shm segment %s (%s)", name, strerror (errno)); goto unlock; } if (ftruncate (shm_fd, size) < 0) { jack_error ("Cannot set size of engine shm " "registry 0 (%s)", strerror (errno)); close (shm_fd); goto unlock; } promiscuous = getenv("JACK_PROMISCUOUS_SERVER"); if ((promiscuous != NULL) && (jack_promiscuous_perms(shm_fd, name, jack_group2gid(promiscuous)) < 0)) goto unlock; close (shm_fd); registry->size = size; strncpy (registry->id, name, sizeof (registry->id)); registry->allocator = GetPID(); si->index = registry->index; si->ptr.attached_at = MAP_FAILED; /* not attached */ rc = 0; /* success */ unlock: jack_shm_unlock_registry (); return rc; } int jack_attach_shm (jack_shm_info_t* si) { int shm_fd; jack_shm_registry_t *registry = &jack_shm_registry[si->index]; if ((shm_fd = shm_open (registry->id, O_RDWR, 0666)) < 0) { jack_error ("Cannot open shm segment %s (%s)", registry->id, strerror (errno)); return -1; } if ((si->ptr.attached_at = mmap (0, registry->size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { jack_error ("Cannot mmap shm segment %s (%s)", registry->id, strerror (errno)); close (shm_fd); return -1; } close (shm_fd); return 0; } int jack_attach_shm_read (jack_shm_info_t* si) { int shm_fd; jack_shm_registry_t *registry = &jack_shm_registry[si->index]; if ((shm_fd = shm_open (registry->id, O_RDONLY, 0666)) < 0) { jack_error ("Cannot open shm segment %s (%s)", registry->id, strerror (errno)); return -1; } if ((si->ptr.attached_at = mmap (0, registry->size, PROT_READ, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { jack_error ("Cannot mmap shm segment %s (%s)", registry->id, strerror (errno)); close (shm_fd); return -1; } close (shm_fd); return 0; } #elif WIN32 static int jack_access_registry (jack_shm_info_t *ri) { /* registry must be locked */ HANDLE shm_fd; strncpy (registry_id, "jack-shm-registry", sizeof (registry_id)); /* try to open an existing segment */ if ((shm_fd = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, registry_id)) == NULL) { int rc = GetLastError(); if (rc != ERROR_FILE_NOT_FOUND) { jack_error ("Cannot open existing shm registry segment (%ld)", rc); } return rc; } if ((ri->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, JACK_SHM_REGISTRY_SIZE)) == NULL) { jack_error ("Cannot mmap shm registry segment (%ld)", GetLastError()); jack_remove_shm (®istry_id); CloseHandle (shm_fd); return EINVAL; } /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); //CloseHandle(shm_fd); // TO CHECK return 0; } static int jack_create_registry (jack_shm_info_t *ri) { /* registry must be locked */ HANDLE shm_fd; strncpy (registry_id, "jack-shm-registry", sizeof (registry_id)); if ((shm_fd = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, JACK_SHM_REGISTRY_SIZE, registry_id)) == NULL || (shm_fd == INVALID_HANDLE_VALUE)) { int rc = GetLastError(); jack_error ("Cannot create shm registry segment (%ld)", rc); return rc; } if ((ri->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, JACK_SHM_REGISTRY_SIZE)) == NULL) { jack_error ("Cannot mmap shm registry segment (%ld)", GetLastError()); jack_remove_shm (®istry_id); CloseHandle (shm_fd); return EINVAL; } /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); /* initialize registry contents */ jack_shm_init_registry (); //CloseHandle(shm_fd); // TO CHECK return 0; } static void jack_remove_shm (jack_shm_id_t *id) { /* nothing to do */ } void jack_release_shm (jack_shm_info_t* si) { /* registry may or may not be locked */ if (si->ptr.attached_at != NULL) { UnmapViewOfFile (si->ptr.attached_at); } } void jack_release_lib_shm (jack_shm_info_t* si) { jack_release_shm(si); } int jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) { jack_shm_registry_t* registry; HANDLE shm_fd; int rc = -1; char name[SHM_NAME_MAX+1]; if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } if ((registry = jack_get_free_shm_info ()) == NULL) { jack_error ("shm registry full"); goto unlock; } snprintf (name, sizeof (name), "jack-%d-%d", GetUID(), registry->index); if (strlen (name) >= sizeof (registry->id)) { jack_error ("shm segment name too long %s", name); goto unlock; } if ((shm_fd = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, name)) == NULL || (shm_fd == INVALID_HANDLE_VALUE)) { int rc = GetLastError(); jack_error ("Cannot create shm segment (%ld)",rc); goto unlock; } //CloseHandle (shm_fd); // TO CHECK registry->size = size; strncpy (registry->id, name, sizeof (registry->id)); registry->allocator = _getpid(); si->index = registry->index; si->ptr.attached_at = NULL; /* not attached */ rc = 0; /* success */ unlock: jack_shm_unlock_registry (); return rc; } int jack_attach_shm (jack_shm_info_t* si) { HANDLE shm_fd; jack_shm_registry_t *registry = &jack_shm_registry[si->index]; if ((shm_fd = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, registry->id)) == NULL) { int rc = GetLastError(); jack_error ("Cannot open shm segment (%ld)",rc); return -1; } if ((si->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, registry->size)) == NULL) { jack_error ("Cannot mmap shm segment (%ld)", GetLastError()); jack_remove_shm (®istry_id); CloseHandle (shm_fd); return -1; } //CloseHandle (shm_fd); // TO CHECK return 0; } int jack_attach_shm_read (jack_shm_info_t* si) { HANDLE shm_fd; jack_shm_registry_t *registry = &jack_shm_registry[si->index]; if ((shm_fd = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, registry->id)) == NULL) { int rc = GetLastError(); jack_error ("Cannot open shm segment (%ld)",rc); return -1; } if ((si->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_READ, 0, 0, registry->size)) == NULL) { jack_error("Cannot mmap shm segment (%ld)", GetLastError()); jack_remove_shm(®istry_id); CloseHandle(shm_fd); return -1; } //CloseHandle (shm_fd); // TO CHECK return 0; } #else /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * System V interface-dependent functions * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* gain addressability to existing SHM registry segment * * sets up global registry pointers, if successful * * returns: 0 if existing registry accessed successfully * ENOENT if registry does not exist * EINVAL if registry exists, but has the wrong size * other nonzero error code if unable to access registry */ static int jack_access_registry (jack_shm_info_t *ri) { /* registry must be locked */ /* try without IPC_CREAT to get existing segment */ if ((registry_id = shmget (JACK_SHM_REGISTRY_KEY, JACK_SHM_REGISTRY_SIZE, 0666)) < 0) { switch (errno) { case ENOENT: /* segment does not exist */ return ENOENT; case EINVAL: /* segment exists, but too small */ /* attempt minimum size access */ registry_id = shmget (JACK_SHM_REGISTRY_KEY, 1, 0666); return EINVAL; default: /* or other error */ jack_error ("unable to access shm registry (%s)", strerror (errno)); return errno; } } if ((ri->ptr.attached_at = shmat (registry_id, 0, 0)) < 0) { jack_error ("Cannot attach shm registry segment (%s)", strerror (errno)); return EINVAL; } /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); return 0; } /* create a new SHM registry segment * * sets up global registry pointers, if successful * * returns: 0 if registry created successfully * nonzero error code if unable to allocate a new registry */ static int jack_create_registry (jack_shm_info_t *ri) { /* registry must be locked */ if ((registry_id = shmget (JACK_SHM_REGISTRY_KEY, JACK_SHM_REGISTRY_SIZE, 0666|IPC_CREAT)) < 0) { jack_error ("Cannot create shm registry segment (%s)", strerror (errno)); return errno; } if ((ri->ptr.attached_at = shmat (registry_id, 0, 0)) < 0) { jack_error ("Cannot attach shm registry segment (%s)", strerror (errno)); return EINVAL; } /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); /* initialize registry contents */ jack_shm_init_registry (); return 0; } static void jack_remove_shm (jack_shm_id_t *id) { /* registry may or may not be locked */ shmctl (*id, IPC_RMID, NULL); } void jack_release_shm (jack_shm_info_t* si) { /* registry may or may not be locked */ if (si->ptr.attached_at != MAP_FAILED) { shmdt (si->ptr.attached_at); } } void jack_release_lib_shm (jack_shm_info_t* si) { jack_release_shm(si); } int jack_shmalloc (const char* name_not_used, jack_shmsize_t size, jack_shm_info_t* si) { int shmflags; int shmid; int rc = -1; jack_shm_registry_t* registry; if (jack_shm_lock_registry () < 0) { jack_error ("jack_shm_lock_registry fails..."); return -1; } if ((registry = jack_get_free_shm_info ())) { shmflags = 0666 | IPC_CREAT | IPC_EXCL; if ((shmid = shmget (IPC_PRIVATE, size, shmflags)) >= 0) { registry->size = size; registry->id = shmid; registry->allocator = getpid(); si->index = registry->index; si->ptr.attached_at = MAP_FAILED; /* not attached */ rc = 0; } else { jack_error ("Cannot create shm segment %s (%s)", name_not_used, strerror (errno)); } } jack_shm_unlock_registry (); return rc; } int jack_attach_shm (jack_shm_info_t* si) { if ((si->ptr.attached_at = shmat (jack_shm_registry[si->index].id, 0, 0)) < 0) { jack_error ("Cannot attach shm segment (%s)", strerror (errno)); jack_release_shm_info (si->index); return -1; } return 0; } int jack_attach_shm_read (jack_shm_info_t* si) { if ((si->ptr.attached_at = shmat (jack_shm_registry[si->index].id, 0, SHM_RDONLY)) < 0) { jack_error ("Cannot attach shm segment (%s)", strerror (errno)); jack_release_shm_info (si->index); return -1; } return 0; } #endif /* !USE_POSIX_SHM */ 1.9.12~dfsg/common/JackAudioPort.cpp0000644000000000000000000001221313214314510016032 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackGlobals.h" #include "JackEngineControl.h" #include "JackPortType.h" #include #if defined (__APPLE__) #include #elif defined (__SSE__) && !defined (__sun__) #include #elif defined (__ARM_NEON__) #include #endif namespace Jack { static void AudioBufferInit(void* buffer, size_t buffer_size, jack_nframes_t) { memset(buffer, 0, buffer_size); } static inline void MixAudioBuffer(jack_default_audio_sample_t* mixbuffer, jack_default_audio_sample_t* buffer, jack_nframes_t frames) { #ifdef __APPLE__ vDSP_vadd(buffer, 1, mixbuffer, 1, mixbuffer, 1, frames); #else jack_nframes_t frames_group = frames / 4; frames = frames % 4; while (frames_group > 0) { #if defined (__SSE__) && !defined (__sun__) __m128 vec = _mm_add_ps(_mm_load_ps(mixbuffer), _mm_load_ps(buffer)); _mm_store_ps(mixbuffer, vec); mixbuffer += 4; buffer += 4; frames_group--; #elif defined (__ARM_NEON__) float32x4_t vec = vaddq_f32(vld1q_f32(mixbuffer), vld1q_f32(buffer)); vst1q_f32(mixbuffer, vec); mixbuffer += 4; buffer += 4; frames_group--; #else register jack_default_audio_sample_t mixFloat1 = *mixbuffer; register jack_default_audio_sample_t sourceFloat1 = *buffer; register jack_default_audio_sample_t mixFloat2 = *(mixbuffer + 1); register jack_default_audio_sample_t sourceFloat2 = *(buffer + 1); register jack_default_audio_sample_t mixFloat3 = *(mixbuffer + 2); register jack_default_audio_sample_t sourceFloat3 = *(buffer + 2); register jack_default_audio_sample_t mixFloat4 = *(mixbuffer + 3); register jack_default_audio_sample_t sourceFloat4 = *(buffer + 3); buffer += 4; frames_group--; mixFloat1 += sourceFloat1; mixFloat2 += sourceFloat2; mixFloat3 += sourceFloat3; mixFloat4 += sourceFloat4; *mixbuffer = mixFloat1; *(mixbuffer + 1) = mixFloat2; *(mixbuffer + 2) = mixFloat3; *(mixbuffer + 3) = mixFloat4; mixbuffer += 4; #endif } while (frames > 0) { register jack_default_audio_sample_t mixFloat1 = *mixbuffer; register jack_default_audio_sample_t sourceFloat1 = *buffer; buffer++; frames--; mixFloat1 += sourceFloat1; *mixbuffer = mixFloat1; mixbuffer++; } #endif } static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes) { void* buffer; // Copy first buffer #if defined (__SSE__) && !defined (__sun__) jack_nframes_t frames_group = nframes / 4; jack_nframes_t remaining_frames = nframes % 4; jack_default_audio_sample_t* source = static_cast(src_buffers[0]); jack_default_audio_sample_t* target = static_cast(mixbuffer); while (frames_group > 0) { __m128 vec = _mm_load_ps(source); _mm_store_ps(target, vec); source += 4; target += 4; --frames_group; } for (jack_nframes_t i = 0; i != remaining_frames; ++i) { target[i] = source[i]; } #elif defined (__ARM_NEON__) jack_nframes_t frames_group = nframes / 4; jack_nframes_t remaining_frames = nframes % 4; jack_default_audio_sample_t* source = static_cast(src_buffers[0]); jack_default_audio_sample_t* target = static_cast(mixbuffer); while (frames_group > 0) { float32x4_t vec = vld1q_f32(source); vst1q_f32(target, vec); source += 4; target += 4; --frames_group; } for (jack_nframes_t i = 0; i != remaining_frames; ++i) { target[i] = source[i]; } #else memcpy(mixbuffer, src_buffers[0], nframes * sizeof(jack_default_audio_sample_t)); #endif // Mix remaining buffers for (int i = 1; i < src_count; ++i) { buffer = src_buffers[i]; MixAudioBuffer(static_cast(mixbuffer), static_cast(buffer), nframes); } } static size_t AudioBufferSize() { return GetEngineControl()->fBufferSize * sizeof(jack_default_audio_sample_t); } const JackPortType gAudioPortType = { JACK_DEFAULT_AUDIO_TYPE, AudioBufferSize, AudioBufferInit, AudioBufferMixdown }; } // namespace Jack 1.9.12~dfsg/common/timestamps.c0000644000000000000000000000374213214314510015170 0ustar rootroot/* Copyright (C) 2002-2003 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "timestamps.h" #include "JackTime.h" typedef struct { jack_time_t when; const char *what; } jack_timestamp_t; static jack_timestamp_t *timestamps = 0; static unsigned long timestamp_cnt = 0; static unsigned long timestamp_index; void jack_init_timestamps (unsigned long howmany) { if (timestamps) { free (timestamps); } timestamps = (jack_timestamp_t *) malloc (howmany * sizeof(jack_timestamp_t)); timestamp_cnt = howmany; memset (timestamps, 0, sizeof(jack_timestamp_t) * howmany); timestamp_index = 0; } void jack_timestamp (const char *what) { if (timestamp_index < timestamp_cnt) { timestamps[timestamp_index].when = GetMicroSeconds(); timestamps[timestamp_index].what = what; ++timestamp_index; } } void jack_dump_timestamps (FILE *out) { unsigned long i; for (i = 0; i < timestamp_index; ++i) { fprintf (out, "%-.32s %" PRIu64 " %" PRIu64, timestamps[i].what, timestamps[i].when, timestamps[i].when - timestamps[0].when); if (i > 0) { fprintf (out, " %" PRIu64, timestamps[i].when - timestamps[i-1].when); } fputc ('\n', out); } } void jack_reset_timestamps () { timestamp_index = 0; } 1.9.12~dfsg/common/JackDriverLoader.cpp0000644000000000000000000007514013214314510016516 0ustar rootroot/* Copyright (C) 2001-2005 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackDriverLoader.h" #include "JackDriverInfo.h" #include "JackConstants.h" #include "JackError.h" #include #include #include #include #ifndef WIN32 #include #endif #ifdef WIN32 static char* locate_dll_driver_dir() { HMODULE libjack_handle = NULL; GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(locate_dll_driver_dir), &libjack_handle); // For WIN32 ADDON_DIR is defined in JackConstants.h as relative path char driver_dir_storage[512]; if (3 < GetModuleFileName(libjack_handle, driver_dir_storage, 512)) { char *p = strrchr(driver_dir_storage, '\\'); if (p && (p != driver_dir_storage)) { *p = 0; } jack_info("Drivers/internals found in : %s", driver_dir_storage); strcat(driver_dir_storage, "/"); strcat(driver_dir_storage, ADDON_DIR); return strdup(driver_dir_storage); } else { jack_error("Cannot get JACK dll directory : %d", GetLastError()); return NULL; } } static char* locate_driver_dir(HANDLE& file, WIN32_FIND_DATA& filedata) { // Search drivers/internals iin the same folder of "libjackserver.dll" char* driver_dir = locate_dll_driver_dir(); char dll_filename[512]; snprintf(dll_filename, sizeof(dll_filename), "%s/*.dll", driver_dir); file = (HANDLE)FindFirstFile(dll_filename, &filedata); if (file == INVALID_HANDLE_VALUE) { jack_error("Drivers not found "); free(driver_dir); return NULL; } else { return driver_dir; } } #endif jack_driver_desc_t* jackctl_driver_get_desc(jackctl_driver_t * driver); void jack_print_driver_options(jack_driver_desc_t* desc, FILE* file) { unsigned long i; char arg_default[JACK_DRIVER_PARAM_STRING_MAX + 1]; for (i = 0; i < desc->nparams; i++) { switch (desc->params[i].type) { case JackDriverParamInt: sprintf (arg_default, "%" "i", desc->params[i].value.i); break; case JackDriverParamUInt: sprintf (arg_default, "%" "u", desc->params[i].value.ui); break; case JackDriverParamChar: sprintf (arg_default, "%c", desc->params[i].value.c); break; case JackDriverParamString: if (desc->params[i].value.str && strcmp (desc->params[i].value.str, "") != 0) { sprintf (arg_default, "%s", desc->params[i].value.str); } else { sprintf (arg_default, "none"); } break; case JackDriverParamBool: sprintf (arg_default, "%s", desc->params[i].value.i ? "true" : "false"); break; } fprintf(file, "\t-%c, --%s \t%s (default: %s)\n", desc->params[i].character, desc->params[i].name, desc->params[i].long_desc, arg_default); } } static void jack_print_driver_param_usage (jack_driver_desc_t* desc, unsigned long param, FILE *file) { fprintf (file, "Usage information for the '%s' parameter for driver '%s':\n", desc->params[param].name, desc->name); fprintf (file, "%s\n", desc->params[param].long_desc); } void jack_free_driver_params(JSList * driver_params) { JSList*node_ptr = driver_params; JSList*next_node_ptr; while (node_ptr) { next_node_ptr = node_ptr->next; free(node_ptr->data); free(node_ptr); node_ptr = next_node_ptr; } } int jack_parse_driver_params(jack_driver_desc_t* desc, int argc, char* argv[], JSList** param_ptr) { struct option * long_options; char* options, * options_ptr; unsigned long i; int opt; unsigned int param_index; JSList* params = NULL; jack_driver_param_t * driver_param; if (argc <= 1) { *param_ptr = NULL; return 0; } /* check for help */ if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { if (argc > 2) { for (i = 0; i < desc->nparams; i++) { if (strcmp (desc->params[i].name, argv[2]) == 0) { jack_print_driver_param_usage (desc, i, stdout); return 1; } } fprintf (stderr, "Jackd: unknown option '%s' " "for driver '%s'\n", argv[2], desc->name); } jack_log("Parameters for driver '%s' (all parameters are optional):", desc->name); jack_print_driver_options (desc, stdout); return 1; } /* set up the stuff for getopt */ options = (char*)calloc (desc->nparams * 3 + 1, sizeof (char)); long_options = (option*)calloc (desc->nparams + 1, sizeof (struct option)); options_ptr = options; for (i = 0; i < desc->nparams; i++) { sprintf (options_ptr, "%c::", desc->params[i].character); options_ptr += 3; long_options[i].name = desc->params[i].name; long_options[i].flag = NULL; long_options[i].val = desc->params[i].character; long_options[i].has_arg = optional_argument; } /* create the params */ optind = 0; opterr = 0; while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { if (opt == ':' || opt == '?') { if (opt == ':') { fprintf (stderr, "Missing option to argument '%c'\n", optopt); } else { fprintf (stderr, "Unknownage with option '%c'\n", optopt); } fprintf (stderr, "Options for driver '%s':\n", desc->name); jack_print_driver_options (desc, stderr); return 1; } for (param_index = 0; param_index < desc->nparams; param_index++) { if (opt == desc->params[param_index].character) { break; } } driver_param = (jack_driver_param_t*)calloc (1, sizeof (jack_driver_param_t)); driver_param->character = desc->params[param_index].character; if (!optarg && optind < argc && strlen(argv[optind]) && argv[optind][0] != '-') { optarg = argv[optind]; } if (optarg) { switch (desc->params[param_index].type) { case JackDriverParamInt: driver_param->value.i = atoi(optarg); break; case JackDriverParamUInt: driver_param->value.ui = strtoul(optarg, NULL, 10); break; case JackDriverParamChar: driver_param->value.c = optarg[0]; break; case JackDriverParamString: strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX); break; case JackDriverParamBool: if (strcasecmp("false", optarg) == 0 || strcasecmp("off", optarg) == 0 || strcasecmp("no", optarg) == 0 || strcasecmp("0", optarg) == 0 || strcasecmp("(null)", optarg) == 0 ) { driver_param->value.i = false; } else { driver_param->value.i = true; } break; } } else { if (desc->params[param_index].type == JackDriverParamBool) { driver_param->value.i = true; } else { driver_param->value = desc->params[param_index].value; } } params = jack_slist_append (params, driver_param); } free (options); free (long_options); if (param_ptr) { *param_ptr = params; } return 0; } SERVER_EXPORT int jackctl_driver_params_parse(jackctl_driver *driver_ptr, int argc, char* argv[]) { struct option* long_options; char* options, * options_ptr; unsigned long i; int opt; JSList* node_ptr; jackctl_parameter_t * param = NULL; union jackctl_parameter_value value; if (argc <= 1) { return 0; } const JSList* driver_params = jackctl_driver_get_parameters(driver_ptr); if (driver_params == NULL) { return 1; } jack_driver_desc_t* desc = jackctl_driver_get_desc(driver_ptr); /* check for help */ if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { if (argc > 2) { for (i = 0; i < desc->nparams; i++) { if (strcmp (desc->params[i].name, argv[2]) == 0) { jack_print_driver_param_usage (desc, i, stdout); return 1; } } fprintf (stderr, "Jackd: unknown option '%s' " "for driver '%s'\n", argv[2], desc->name); } jack_log("Parameters for driver '%s' (all parameters are optional):", desc->name); jack_print_driver_options (desc, stdout); return 1; } /* set up the stuff for getopt */ options = (char*)calloc (desc->nparams * 3 + 1, sizeof (char)); long_options = (option*)calloc (desc->nparams + 1, sizeof (struct option)); options_ptr = options; for (i = 0; i < desc->nparams; i++) { sprintf(options_ptr, "%c::", desc->params[i].character); options_ptr += 3; long_options[i].name = desc->params[i].name; long_options[i].flag = NULL; long_options[i].val = desc->params[i].character; long_options[i].has_arg = optional_argument; } /* create the params */ optind = 0; opterr = 0; while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { if (opt == ':' || opt == '?') { if (opt == ':') { fprintf (stderr, "Missing option to argument '%c'\n", optopt); } else { fprintf (stderr, "Unknownage with option '%c'\n", optopt); } fprintf (stderr, "Options for driver '%s':\n", desc->name); jack_print_driver_options(desc, stderr); return 1; } node_ptr = (JSList *)driver_params; while (node_ptr) { param = (jackctl_parameter_t*)node_ptr->data; if (opt == jackctl_parameter_get_id(param)) { break; } node_ptr = node_ptr->next; } if (!optarg && optind < argc && strlen(argv[optind]) && argv[optind][0] != '-') { optarg = argv[optind]; } if (optarg) { switch (jackctl_parameter_get_type(param)) { case JackDriverParamInt: value.i = atoi(optarg); jackctl_parameter_set_value(param, &value); break; case JackDriverParamUInt: value.ui = strtoul(optarg, NULL, 10); jackctl_parameter_set_value(param, &value); break; case JackDriverParamChar: value.c = optarg[0]; jackctl_parameter_set_value(param, &value); break; case JackDriverParamString: strncpy(value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX); jackctl_parameter_set_value(param, &value); break; case JackDriverParamBool: if (strcasecmp("false", optarg) == 0 || strcasecmp("off", optarg) == 0 || strcasecmp("no", optarg) == 0 || strcasecmp("0", optarg) == 0 || strcasecmp("(null)", optarg) == 0 ) { value.i = false; } else { value.i = true; } jackctl_parameter_set_value(param, &value); break; } } else { if (jackctl_parameter_get_type(param) == JackParamBool) { value.i = true; } else { value = jackctl_parameter_get_default_value(param); } jackctl_parameter_set_value(param, &value); } } free(options); free(long_options); return 0; } jack_driver_desc_t* jack_find_driver_descriptor (JSList * drivers, const char* name) { jack_driver_desc_t* desc = 0; JSList* node; for (node = drivers; node; node = jack_slist_next (node)) { desc = (jack_driver_desc_t*) node->data; if (strcmp (desc->name, name) != 0) { desc = NULL; } else { break; } } return desc; } static void* check_symbol(const char* sofile, const char* symbol, const char* driver_dir, void** res_dllhandle = NULL) { void* dlhandle; void* res = NULL; char filename[1024]; sprintf(filename, "%s/%s", driver_dir, sofile); if ((dlhandle = LoadDriverModule(filename)) == NULL) { #ifdef WIN32 jack_error ("Could not open component .dll '%s': %ld", filename, GetLastError()); #else jack_error ("Could not open component .so '%s': %s", filename, dlerror()); #endif } else { res = (void*)GetDriverProc(dlhandle, symbol); if (res_dllhandle) { *res_dllhandle = dlhandle; } else { UnloadDriverModule(dlhandle); } } return res; } static jack_driver_desc_t* jack_get_descriptor (JSList* drivers, const char* sofile, const char* symbol, const char* driver_dir) { jack_driver_desc_t* descriptor = NULL; jack_driver_desc_t* other_descriptor; JackDriverDescFunction so_get_descriptor = NULL; char filename[1024]; JSList* node; void* dlhandle = NULL; sprintf(filename, "%s/%s", driver_dir, sofile); so_get_descriptor = (JackDriverDescFunction)check_symbol(sofile, symbol, driver_dir, &dlhandle); if (so_get_descriptor == NULL) { jack_error("jack_get_descriptor : dll %s is not a driver", sofile); goto error; } if ((descriptor = so_get_descriptor ()) == NULL) { jack_error("Driver from '%s' returned NULL descriptor", filename); goto error; } /* check it doesn't exist already */ for (node = drivers; node; node = jack_slist_next (node)) { other_descriptor = (jack_driver_desc_t*) node->data; if (strcmp(descriptor->name, other_descriptor->name) == 0) { jack_error("The drivers in '%s' and '%s' both have the name '%s'; using the first", other_descriptor->file, filename, other_descriptor->name); /* FIXME: delete the descriptor */ goto error; } } strncpy(descriptor->file, filename, JACK_PATH_MAX); error: if (dlhandle) { UnloadDriverModule(dlhandle); } return descriptor; } #ifdef WIN32 JSList * jack_drivers_load(JSList * drivers) { //char dll_filename[512]; WIN32_FIND_DATA filedata; HANDLE file; const char* ptr = NULL; JSList* driver_list = NULL; jack_driver_desc_t* desc = NULL; char* driver_dir = locate_driver_dir(file, filedata); if (!driver_dir) { jack_error("Driver folder not found"); goto error; } do { /* check the filename is of the right format */ if (strncmp ("jack_", filedata.cFileName, 5) != 0) { continue; } ptr = strrchr (filedata.cFileName, '.'); if (!ptr) { continue; } ptr++; if (strncmp ("dll", ptr, 3) != 0) { continue; } /* check if dll is an internal client */ if (check_symbol(filedata.cFileName, "jack_internal_initialize", driver_dir) != NULL) { continue; } desc = jack_get_descriptor (drivers, filedata.cFileName, "driver_get_descriptor", driver_dir); if (desc) { driver_list = jack_slist_append (driver_list, desc); } else { jack_error ("jack_get_descriptor returns null for \'%s\'", filedata.cFileName); } } while (FindNextFile(file, &filedata)); if (!driver_list) { jack_error ("Could not find any drivers in %s!", driver_dir); } error: if (driver_dir) { free(driver_dir); } FindClose(file); return driver_list; } #else JSList* jack_drivers_load (JSList * drivers) { struct dirent * dir_entry; DIR * dir_stream; const char* ptr; int err; JSList* driver_list = NULL; jack_driver_desc_t* desc = NULL; const char* driver_dir; if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { driver_dir = ADDON_DIR; } /* search through the driver_dir and add get descriptors from the .so files in it */ dir_stream = opendir (driver_dir); if (!dir_stream) { jack_error ("Could not open driver directory %s: %s", driver_dir, strerror (errno)); return NULL; } while ((dir_entry = readdir(dir_stream))) { /* check the filename is of the right format */ if (strncmp ("jack_", dir_entry->d_name, 5) != 0) { continue; } ptr = strrchr (dir_entry->d_name, '.'); if (!ptr) { continue; } ptr++; if (strncmp ("so", ptr, 2) != 0) { continue; } /* check if dll is an internal client */ if (check_symbol(dir_entry->d_name, "jack_internal_initialize", driver_dir) != NULL) { continue; } desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor", driver_dir); if (desc) { driver_list = jack_slist_append (driver_list, desc); } else { jack_error ("jack_get_descriptor returns null for \'%s\'", dir_entry->d_name); } } err = closedir (dir_stream); if (err) { jack_error ("Error closing driver directory %s: %s", driver_dir, strerror (errno)); } if (!driver_list) { jack_error ("Could not find any drivers in %s!", driver_dir); return NULL; } return driver_list; } #endif #ifdef WIN32 JSList* jack_internals_load(JSList * internals) { ///char dll_filename[512]; WIN32_FIND_DATA filedata; HANDLE file; const char* ptr = NULL; JSList* driver_list = NULL; jack_driver_desc_t* desc; char* driver_dir = locate_driver_dir(file, filedata); if (!driver_dir) { jack_error("Driver folder not found"); goto error; } do { ptr = strrchr (filedata.cFileName, '.'); if (!ptr) { continue; } ptr++; if (strncmp ("dll", ptr, 3) != 0) { continue; } /* check if dll is an internal client */ if (check_symbol(filedata.cFileName, "jack_internal_initialize", driver_dir) == NULL) { continue; } desc = jack_get_descriptor (internals, filedata.cFileName, "jack_get_descriptor", driver_dir); if (desc) { driver_list = jack_slist_append (driver_list, desc); } else { jack_error ("jack_get_descriptor returns null for \'%s\'", filedata.cFileName); } } while (FindNextFile(file, &filedata)); if (!driver_list) { jack_error ("Could not find any internals in %s!", driver_dir); } error: if (driver_dir) { free(driver_dir); } FindClose(file); return driver_list; } #else JSList* jack_internals_load(JSList * internals) { struct dirent * dir_entry; DIR * dir_stream; const char* ptr; int err; JSList* driver_list = NULL; jack_driver_desc_t* desc; const char* driver_dir; if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { driver_dir = ADDON_DIR; } /* search through the driver_dir and add get descriptors from the .so files in it */ dir_stream = opendir (driver_dir); if (!dir_stream) { jack_error ("Could not open driver directory %s: %s\n", driver_dir, strerror (errno)); return NULL; } while ((dir_entry = readdir(dir_stream))) { ptr = strrchr (dir_entry->d_name, '.'); if (!ptr) { continue; } ptr++; if (strncmp ("so", ptr, 2) != 0) { continue; } /* check if dll is an internal client */ if (check_symbol(dir_entry->d_name, "jack_internal_initialize", driver_dir) == NULL) { continue; } desc = jack_get_descriptor (internals, dir_entry->d_name, "jack_get_descriptor", driver_dir); if (desc) { driver_list = jack_slist_append (driver_list, desc); } else { jack_error ("jack_get_descriptor returns null for \'%s\'", dir_entry->d_name); } } err = closedir (dir_stream); if (err) { jack_error ("Error closing internal directory %s: %s\n", driver_dir, strerror (errno)); } if (!driver_list) { jack_error ("Could not find any internals in %s!", driver_dir); return NULL; } return driver_list; } #endif Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc, Jack::JackLockedEngine* engine, Jack::JackSynchro* synchro, const JSList* params) { #ifdef WIN32 int errstr; #else const char* errstr; #endif fHandle = LoadDriverModule (driver_desc->file); if (fHandle == NULL) { #ifdef WIN32 if ((errstr = GetLastError ()) != 0) { jack_error ("Can't load \"%s\": %ld", driver_desc->file, errstr); #else if ((errstr = dlerror ()) != 0) { jack_error ("Can't load \"%s\": %s", driver_desc->file, errstr); #endif } else { jack_error ("Error loading driver shared object %s", driver_desc->file); } return NULL; } fInitialize = (driverInitialize)GetDriverProc(fHandle, "driver_initialize"); #ifdef WIN32 if ((fInitialize == NULL) && (errstr = GetLastError ()) != 0) { #else if ((fInitialize == NULL) && (errstr = dlerror ()) != 0) { #endif jack_error("No initialize function in shared object %s\n", driver_desc->file); return NULL; } fBackend = fInitialize(engine, synchro, params); return fBackend; } JackDriverInfo::~JackDriverInfo() { delete fBackend; if (fHandle) { UnloadDriverModule(fHandle); } } SERVER_EXPORT jack_driver_desc_t* jack_driver_descriptor_construct( const char * name, jack_driver_type_t type, const char * description, jack_driver_desc_filler_t * filler_ptr) { size_t name_len; size_t description_len; jack_driver_desc_t* desc_ptr; name_len = strlen(name); description_len = strlen(description); if (name_len > sizeof(desc_ptr->name) - 1 || description_len > sizeof(desc_ptr->desc) - 1) { assert(false); return 0; } desc_ptr = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); if (desc_ptr == NULL) { jack_error("Error calloc() failed to allocate memory for driver descriptor struct"); return 0; } memcpy(desc_ptr->name, name, name_len + 1); memcpy(desc_ptr->desc, description, description_len + 1); desc_ptr->nparams = 0; desc_ptr->type = type; if (filler_ptr != NULL) { filler_ptr->size = 0; } return desc_ptr; } SERVER_EXPORT int jack_driver_descriptor_add_parameter( jack_driver_desc_t* desc_ptr, jack_driver_desc_filler_t * filler_ptr, const char* name, char character, jack_driver_param_type_t type, const jack_driver_param_value_t * value_ptr, jack_driver_param_constraint_desc_t * constraint, const char* short_desc, const char* long_desc) { size_t name_len; size_t short_desc_len; size_t long_desc_len; jack_driver_param_desc_t * param_ptr; size_t newsize; name_len = strlen(name); short_desc_len = strlen(short_desc); if (long_desc != NULL) { long_desc_len = strlen(long_desc); } else { long_desc = short_desc; long_desc_len = short_desc_len; } if (name_len > sizeof(param_ptr->name) - 1 || short_desc_len > sizeof(param_ptr->short_desc) - 1 || long_desc_len > sizeof(param_ptr->long_desc) - 1) { assert(false); return 0; } if (desc_ptr->nparams == filler_ptr->size) { newsize = filler_ptr->size + 20; // most drivers have less than 20 parameters param_ptr = (jack_driver_param_desc_t*)realloc (desc_ptr->params, newsize * sizeof (jack_driver_param_desc_t)); if (param_ptr == NULL) { jack_error("Error realloc() failed for parameter array of %zu elements", newsize); return false; } filler_ptr->size = newsize; desc_ptr->params = param_ptr; } assert(desc_ptr->nparams < filler_ptr->size); param_ptr = desc_ptr->params + desc_ptr->nparams; memcpy(param_ptr->name, name, name_len + 1); param_ptr->character = character; param_ptr->type = type; param_ptr->value = *value_ptr; param_ptr->constraint = constraint; memcpy(param_ptr->short_desc, short_desc, short_desc_len + 1); memcpy(param_ptr->long_desc, long_desc, long_desc_len + 1); desc_ptr->nparams++; return true; } SERVER_EXPORT int jack_constraint_add_enum( jack_driver_param_constraint_desc_t ** constraint_ptr_ptr, uint32_t * array_size_ptr, jack_driver_param_value_t * value_ptr, const char * short_desc) { jack_driver_param_constraint_desc_t * constraint_ptr; uint32_t array_size; jack_driver_param_value_enum_t * possible_value_ptr; size_t len; len = strlen(short_desc) + 1; if (len > sizeof(possible_value_ptr->short_desc)) { assert(false); return false; } constraint_ptr = *constraint_ptr_ptr; if (constraint_ptr == NULL) { constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_constraint_desc_t)); if (constraint_ptr == NULL) { jack_error("calloc() failed to allocate memory for param constraint struct"); return false; } array_size = 0; } else { array_size = *array_size_ptr; } if (constraint_ptr->constraint.enumeration.count == array_size) { array_size += 10; possible_value_ptr = (jack_driver_param_value_enum_t *)realloc( constraint_ptr->constraint.enumeration.possible_values_array, sizeof(jack_driver_param_value_enum_t) * array_size); if (possible_value_ptr == NULL) { jack_error("realloc() failed to (re)allocate memory for possible values array"); return false; } constraint_ptr->constraint.enumeration.possible_values_array = possible_value_ptr; } else { possible_value_ptr = constraint_ptr->constraint.enumeration.possible_values_array; } possible_value_ptr += constraint_ptr->constraint.enumeration.count; constraint_ptr->constraint.enumeration.count++; possible_value_ptr->value = *value_ptr; memcpy(possible_value_ptr->short_desc, short_desc, len); *constraint_ptr_ptr = constraint_ptr; *array_size_ptr = array_size; return true; } SERVER_EXPORT void jack_constraint_free( jack_driver_param_constraint_desc_t * constraint_ptr) { if (constraint_ptr != NULL) { if ((constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) == 0) { free(constraint_ptr->constraint.enumeration.possible_values_array); } free(constraint_ptr); } } #define JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(type, copy) \ JACK_CONSTRAINT_COMPOSE_ENUM(type) \ { \ jack_driver_param_constraint_desc_t * constraint_ptr; \ uint32_t array_size; \ jack_driver_param_value_t value; \ struct jack_constraint_enum_ ## type ## _descriptor * descr_ptr; \ \ constraint_ptr = NULL; \ for (descr_ptr = descr_array_ptr; \ descr_ptr->value; \ descr_ptr++) \ { \ copy; \ if (!jack_constraint_add_enum( \ &constraint_ptr, \ &array_size, \ &value, \ descr_ptr->short_desc)) \ { \ jack_constraint_free(constraint_ptr); \ return NULL; \ } \ } \ \ constraint_ptr->flags = flags; \ \ return constraint_ptr; \ } JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(uint32, value.c = descr_ptr->value); JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(sint32, value.c = descr_ptr->value); JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(char, value.c = descr_ptr->value); JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(str, strcpy(value.str, descr_ptr->value)); 1.9.12~dfsg/common/JackResampler.h0000644000000000000000000000504713214314510015532 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackResampler__ #define __JackResampler__ #include "ringbuffer.h" #include "types.h" namespace Jack { #define DEFAULT_RB_SIZE 32768 #define DEFAULT_ADAPTATIVE_SIZE 2048 inline float Range(float min, float max, float val) { return (val < min) ? min : ((val > max) ? max : val); } /*! \brief Base class for RingBuffer in frames. */ class JackRingBuffer { protected: jack_ringbuffer_t* fRingBuffer; unsigned int fRingBufferSize; public: JackRingBuffer(int size = DEFAULT_RB_SIZE); virtual ~JackRingBuffer(); virtual void Reset(unsigned int new_size); // in frames virtual unsigned int Read(jack_default_audio_sample_t* buffer, unsigned int frames); virtual unsigned int Write(jack_default_audio_sample_t* buffer, unsigned int frames); // in bytes virtual unsigned int Read(void* buffer, unsigned int bytes); virtual unsigned int Write(void* buffer, unsigned int bytes); // in frames virtual unsigned int ReadSpace(); virtual unsigned int WriteSpace(); unsigned int GetError() { return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)) - (fRingBufferSize / 2); } }; /*! \brief Base class for Resampler. */ class JackResampler : public JackRingBuffer { protected: double fRatio; public: JackResampler():JackRingBuffer(),fRatio(1) {} virtual ~JackResampler() {} virtual unsigned int ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames); virtual unsigned int WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames); void SetRatio(double ratio) { fRatio = Range(0.25, 4.0, ratio); } double GetRatio() { return fRatio; } }; } #endif 1.9.12~dfsg/common/jack/0000755000000000000000000000000013214314510013540 5ustar rootroot1.9.12~dfsg/common/jack/intclient.h0000644000000000000000000001133313214314510015703 0ustar rootroot/* * Copyright (C) 2004 Jack O'Quin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __jack_intclient_h__ #define __jack_intclient_h__ #ifdef __cplusplus extern "C" { #endif #include /** * Get an internal client's name. This is useful when @ref * JackUseExactName was not specified on jack_internal_client_load() * and @ref JackNameNotUnique status was returned. In that case, the * actual name will differ from the @a client_name requested. * * @param client requesting JACK client's handle. * * @param intclient handle returned from jack_internal_client_load() * or jack_internal_client_handle(). * * @return NULL if unsuccessful, otherwise pointer to the internal * client name obtained from the heap via malloc(). The caller should * jack_free() this storage when no longer needed. */ char *jack_get_internal_client_name (jack_client_t *client, jack_intclient_t intclient); /** * Return the @ref jack_intclient_t handle for an internal client * running in the JACK server. * * @param client requesting JACK client's handle. * * @param client_name for the internal client of no more than * jack_client_name_size() characters. The name scope is local to the * current server. * * @param status (if non-NULL) an address for JACK to return * information from this operation. This status word is formed by * OR-ing together the relevant @ref JackStatus bits. * * @return Opaque internal client handle if successful. If 0, the * internal client was not found, and @a *status includes the @ref * JackNoSuchClient and @ref JackFailure bits. */ jack_intclient_t jack_internal_client_handle (jack_client_t *client, const char *client_name, jack_status_t *status); /** * Load an internal client into the JACK server. * * Internal clients run inside the JACK server process. They can use * most of the same functions as external clients. Each internal * client is built as a shared object module, which must declare * jack_initialize() and jack_finish() entry points called at load and * unload times. See @ref inprocess.c for an example. * * @param client loading JACK client's handle. * * @param client_name of at most jack_client_name_size() characters * for the internal client to load. The name scope is local to the * current server. * * @param options formed by OR-ing together @ref JackOptions bits. * Only the @ref JackLoadOptions bits are valid. * * @param status (if non-NULL) an address for JACK to return * information from the load operation. This status word is formed by * OR-ing together the relevant @ref JackStatus bits. * * Optional parameters: depending on corresponding [@a options * bits] additional parameters may follow @a status (in this order). * * @arg [@ref JackLoadName] (char *) load_name is the shared * object file from which to load the new internal client (otherwise * use the @a client_name). * * @arg [@ref JackLoadInit] (char *) load_init an arbitary * string passed to the internal client's jack_initialize() routine * (otherwise NULL), of no more than @ref JACK_LOAD_INIT_LIMIT bytes. * * @return Opaque internal client handle if successful. If this is 0, * the load operation failed, the internal client was not loaded, and * @a *status includes the @ref JackFailure bit. */ jack_intclient_t jack_internal_client_load (jack_client_t *client, const char *client_name, jack_options_t options, jack_status_t *status, ...); /** * Unload an internal client from a JACK server. This calls the * intclient's jack_finish() entry point then removes it. See @ref * inprocess.c for an example. * * @param client unloading JACK client's handle. * * @param intclient handle returned from jack_internal_client_load() or * jack_internal_client_handle(). * * @return 0 if successful, otherwise @ref JackStatus bits. */ jack_status_t jack_internal_client_unload (jack_client_t *client, jack_intclient_t intclient); #ifdef __cplusplus } #endif #endif /* __jack_intclient_h__ */ 1.9.12~dfsg/common/jack/jack.h0000644000000000000000000015447513214314510014641 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Jack O'Quin This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_h__ #define __jack_h__ #ifdef __cplusplus extern "C" { #endif #include #include #include /** * Note: More documentation can be found in jack/types.h. */ /************************************************************* * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function * added to the JACK API after the 0.116.2 release. * * Functions that predate this release are marked with * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile * time in a variety of ways. The default definition is empty, * so that these symbols get normal linkage. If you wish to * use all JACK symbols with weak linkage, include * before jack.h. *************************************************************/ #include /** * Call this function to get version of the JACK, in form of several numbers * * @param major_ptr pointer to variable receiving major version of JACK. * * @param minor_ptr pointer to variable receiving minor version of JACK. * * @param major_ptr pointer to variable receiving micro version of JACK. * * @param major_ptr pointer to variable receiving protocol version of JACK. * */ void jack_get_version( int *major_ptr, int *minor_ptr, int *micro_ptr, int *proto_ptr) JACK_OPTIONAL_WEAK_EXPORT; /** * Call this function to get version of the JACK, in form of a string * * @return Human readable string describing JACK version being used. * */ const char * jack_get_version_string(void) JACK_OPTIONAL_WEAK_EXPORT; /** * @defgroup ClientFunctions Creating & manipulating clients * @{ */ /** * Open an external client session with a JACK server. This interface * is more complex but more powerful than jack_client_new(). With it, * clients may choose which of several servers to connect, and control * whether and how to start the server automatically, if it was not * already running. There is also an option for JACK to generate a * unique client name, when necessary. * * @param client_name of at most jack_client_name_size() characters. * The name scope is local to each server. Unless forbidden by the * @ref JackUseExactName option, the server will modify this name to * create a unique variant, if needed. * * @param options formed by OR-ing together @ref JackOptions bits. * Only the @ref JackOpenOptions bits are allowed. * * @param status (if non-NULL) an address for JACK to return * information from the open operation. This status word is formed by * OR-ing together the relevant @ref JackStatus bits. * * * Optional parameters: depending on corresponding [@a options * bits] additional parameters may follow @a status (in this order). * * @arg [@ref JackServerName] (char *) server_name selects * from among several possible concurrent server instances. Server * names are unique to each user. If unspecified, use "default" * unless \$JACK_DEFAULT_SERVER is defined in the process environment. * * @return Opaque client handle if successful. If this is NULL, the * open operation failed, @a *status includes @ref JackFailure and the * caller is not a JACK client. */ jack_client_t * jack_client_open (const char *client_name, jack_options_t options, jack_status_t *status, ...) JACK_OPTIONAL_WEAK_EXPORT; /** * \bold THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED IN * NEW JACK CLIENTS * * @deprecated Please use jack_client_open(). */ jack_client_t * jack_client_new (const char *client_name) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Disconnects an external client from a JACK server. * * @return 0 on success, otherwise a non-zero error code */ int jack_client_close (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a JACK client name * including the final NULL character. This value is a constant. */ int jack_client_name_size (void) JACK_OPTIONAL_WEAK_EXPORT; /** * @return pointer to actual client name. This is useful when @ref * JackUseExactName is not specified on open and @ref * JackNameNotUnique status was returned. In that case, the actual * name will differ from the @a client_name requested. */ char * jack_get_client_name (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Get the session ID for a client name. * * The session manager needs this to reassociate a client name to the session_id. * * The caller is responsible for calling jack_free(3) on any non-NULL * returned value. */ char *jack_get_uuid_for_client_name (jack_client_t *client, const char *client_name) JACK_WEAK_EXPORT; /** * Get the client name for a session_id. * * In order to snapshot the graph connections, the session manager needs to map * session_ids to client names. * * The caller is responsible for calling jack_free(3) on any non-NULL * returned value. */ char *jack_get_client_name_by_uuid (jack_client_t *client, const char *client_uuid ) JACK_WEAK_EXPORT; /** * Load an internal client into the Jack server. * * Internal clients run inside the JACK server process. They can use * most of the same functions as external clients. Each internal * client must declare jack_initialize() and jack_finish() entry * points, called at load and unload times. See inprocess.c for an * example of how to write an internal client. * * @deprecated Please use jack_internal_client_load(). * * @param client_name of at most jack_client_name_size() characters. * * @param load_name of a shared object file containing the code for * the new client. * * @param load_init an arbitary string passed to the jack_initialize() * routine of the new client (may be NULL). * * @return 0 if successful. */ int jack_internal_client_new (const char *client_name, const char *load_name, const char *load_init) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Remove an internal client from a JACK server. * * @deprecated Please use jack_internal_client_unload(). */ void jack_internal_client_close (const char *client_name) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Tell the Jack server that the program is ready to start processing * audio. * * @return 0 on success, otherwise a non-zero error code */ int jack_activate (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to remove this @a client from the process * graph. Also, disconnect all ports belonging to it, since inactive * clients have no port connections. * * @return 0 on success, otherwise a non-zero error code */ int jack_deactivate (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return pid of client. If not available, 0 will be returned. */ int jack_get_client_pid (const char *name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the pthread ID of the thread running the JACK client side * real-time code. */ jack_native_thread_t jack_client_thread_id (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ /** * @param client pointer to JACK client structure. * * Check if the JACK subsystem is running with -R (--realtime). * * @return 1 if JACK is running realtime, 0 otherwise */ int jack_is_realtime (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @defgroup NonCallbackAPI The non-callback API * @{ */ /** * \bold THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED IN * NEW JACK CLIENTS. * * @deprecated Please use jack_cycle_wait() and jack_cycle_signal() functions. */ jack_nframes_t jack_thread_wait (jack_client_t *client, int status) JACK_OPTIONAL_WEAK_EXPORT; /** * Wait until this JACK client should process data. * * @param client - pointer to a JACK client structure * * @return the number of frames of data to process */ jack_nframes_t jack_cycle_wait (jack_client_t* client) JACK_OPTIONAL_WEAK_EXPORT; /** * Signal next clients in the graph. * * @param client - pointer to a JACK client structure * @param status - if non-zero, calling thread should exit */ void jack_cycle_signal (jack_client_t* client, int status) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a thread_callback in the RT thread. * Typical use are in conjunction with @a jack_cycle_wait and @a jack_cycle_signal functions. * The code in the supplied function must be suitable for real-time * execution. That means that it cannot call functions that might * block for a long time. This includes malloc, free, printf, * pthread_mutex_lock, sleep, wait, poll, select, pthread_join, * pthread_cond_wait, etc, etc. See * http://jackit.sourceforge.net/docs/design/design.html#SECTION00411000000000000000 * for more information. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code. */ int jack_set_process_thread(jack_client_t* client, JackThreadCallback thread_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ /** * @defgroup ClientCallbacks Setting Client Callbacks * @{ */ /** * Tell JACK to call @a thread_init_callback once just after * the creation of the thread in which all other callbacks * will be handled. * * The code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code, causing JACK * to remove that client from the process() graph. */ int jack_set_thread_init_callback (jack_client_t *client, JackThreadInitCallback thread_init_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * @param client pointer to JACK client structure. * @param function The jack_shutdown function pointer. * @param arg The arguments for the jack_shutdown function. * * Register a function (and argument) to be called if and when the * JACK server shuts down the client thread. The function must * be written as if it were an asynchonrous POSIX signal * handler --- use only async-safe functions, and remember that it * is executed from another thread. A typical function might * set a flag or write to a pipe so that the rest of the * application knows that the JACK client thread has shut * down. * * NOTE: clients do not need to call this. It exists only * to help more complex clients understand what is going * on. It should be called before jack_client_activate(). * * NOTE: if a client calls this AND jack_on_info_shutdown(), then * in case of a client thread shutdown, the callback * passed to this function will not be called, and the one passed to * jack_on_info_shutdown() will. * * NOTE: application should typically signal another thread to correctly * finish cleanup, that is by calling "jack_client_close" * (since "jack_client_close" cannot be called directly in the context * of the thread that calls the shutdown callback). */ void jack_on_shutdown (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * @param client pointer to JACK client structure. * @param function The jack_info_shutdown function pointer. * @param arg The arguments for the jack_info_shutdown function. * * Register a function (and argument) to be called if and when the * JACK server shuts down the client thread. The function must * be written as if it were an asynchonrous POSIX signal * handler --- use only async-safe functions, and remember that it * is executed from another thread. A typical function might * set a flag or write to a pipe so that the rest of the * application knows that the JACK client thread has shut * down. * * NOTE: clients do not need to call this. It exists only * to help more complex clients understand what is going * on. It should be called before jack_client_activate(). * * NOTE: if a client calls this AND jack_on_shutdown(), then * in case of a client thread shutdown, the callback passed to * jack_on_info_shutdown() will be called. * * NOTE: application should typically signal another thread to correctly * finish cleanup, that is by calling "jack_client_close" * (since "jack_client_close" cannot be called directly in the context * of the thread that calls the shutdown callback). */ void jack_on_info_shutdown (jack_client_t *client, JackInfoShutdownCallback shutdown_callback, void *arg) JACK_WEAK_EXPORT; /** * Tell the Jack server to call @a process_callback whenever there is * work be done, passing @a arg as the second argument. * * The code in the supplied function must be suitable for real-time * execution. That means that it cannot call functions that might * block for a long time. This includes malloc, free, printf, * pthread_mutex_lock, sleep, wait, poll, select, pthread_join, * pthread_cond_wait, etc, etc. See * http://jackit.sourceforge.net/docs/design/design.html#SECTION00411000000000000000 * for more information. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code. */ int jack_set_process_callback (jack_client_t *client, JackProcessCallback process_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a freewheel_callback * whenever we enter or leave "freewheel" mode, passing @a * arg as the second argument. The first argument to the * callback will be non-zero if JACK is entering freewheel * mode, and zero otherwise. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code. */ int jack_set_freewheel_callback (jack_client_t *client, JackFreewheelCallback freewheel_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell JACK to call @a bufsize_callback whenever the size of the the * buffer that will be passed to the @a process_callback is about to * change. Clients that depend on knowing the buffer size must supply * a @a bufsize_callback before activating themselves. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @param client pointer to JACK client structure. * @param bufsize_callback function to call when the buffer size changes. * @param arg argument for @a bufsize_callback. * * @return 0 on success, otherwise a non-zero error code */ int jack_set_buffer_size_callback (jack_client_t *client, JackBufferSizeCallback bufsize_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a srate_callback whenever the system * sample rate changes. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code */ int jack_set_sample_rate_callback (jack_client_t *client, JackSampleRateCallback srate_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a client_registration_callback whenever a * client is registered or unregistered, passing @a arg as a parameter. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code */ int jack_set_client_registration_callback (jack_client_t *client, JackClientRegistrationCallback registration_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a registration_callback whenever a * port is registered or unregistered, passing @a arg as a parameter. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_registration_callback (jack_client_t *client, JackPortRegistrationCallback registration_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a connect_callback whenever a * port is connected or disconnected, passing @a arg as a parameter. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_connect_callback (jack_client_t *client, JackPortConnectCallback connect_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a rename_callback whenever a * port is renamed, passing @a arg as a parameter. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_rename_callback (jack_client_t *client, JackPortRenameCallback rename_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a graph_callback whenever the * processing graph is reordered, passing @a arg as a parameter. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code */ int jack_set_graph_order_callback (jack_client_t *client, JackGraphOrderCallback graph_callback, void *) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a xrun_callback whenever there is a * xrun, passing @a arg as a parameter. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be * suitable for real-time execution. * * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code */ int jack_set_xrun_callback (jack_client_t *client, JackXRunCallback xrun_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ /** * Tell the Jack server to call @a latency_callback whenever it * is necessary to recompute the latencies for some or all * Jack ports. * * @a latency_callback will be called twice each time it is * needed, once being passed JackCaptureLatency and once * JackPlaybackLatency. See @ref LatencyFunctions for * the definition of each type of latency and related functions. * * IMPORTANT: Most JACK clients do NOT need to register a latency * callback. * * Clients that meet any of the following conditions do NOT * need to register a latency callback: * * - have only input ports * - have only output ports * - their output is totally unrelated to their input * - their output is not delayed relative to their input * (i.e. data that arrives in a given process() * callback is processed and output again in the * same callback) * * Clients NOT registering a latency callback MUST also * satisfy this condition: * * - have no multiple distinct internal signal pathways * * This means that if your client has more than 1 input and * output port, and considers them always "correlated" * (e.g. as a stereo pair), then there is only 1 (e.g. stereo) * signal pathway through the client. This would be true, * for example, of a stereo FX rack client that has a * left/right input pair and a left/right output pair. * * However, this is somewhat a matter of perspective. The * same FX rack client could be connected so that its * two input ports were connected to entirely separate * sources. Under these conditions, the fact that the client * does not register a latency callback MAY result * in port latency values being incorrect. * * Clients that do not meet any of those conditions SHOULD * register a latency callback. * * See the documentation for @ref jack_port_set_latency_range() * on how the callback should operate. Remember that the @a mode * argument given to the latency callback will need to be * passed into @ref jack_port_set_latency_range() * * @return 0 on success, otherwise a non-zero error code */ int jack_set_latency_callback (jack_client_t *client, JackLatencyCallback latency_callback, void *) JACK_WEAK_EXPORT; /*@}*/ /** * @defgroup ServerClientControl Controlling & querying JACK server operation * @{ */ /** * Start/Stop JACK's "freewheel" mode. * * When in "freewheel" mode, JACK no longer waits for * any external event to begin the start of the next process * cycle. * * As a result, freewheel mode causes "faster than realtime" * execution of a JACK graph. If possessed, real-time * scheduling is dropped when entering freewheel mode, and * if appropriate it is reacquired when stopping. * * IMPORTANT: on systems using capabilities to provide real-time * scheduling (i.e. Linux kernel 2.4), if onoff is zero, this function * must be called from the thread that originally called jack_activate(). * This restriction does not apply to other systems (e.g. Linux kernel 2.6 * or OS X). * * @param client pointer to JACK client structure * @param onoff if non-zero, freewheel mode starts. Otherwise * freewheel mode ends. * * @return 0 on success, otherwise a non-zero error code. */ int jack_set_freewheel(jack_client_t* client, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * Change the buffer size passed to the @a process_callback. * * This operation stops the JACK engine process cycle, then calls all * registered @a bufsize_callback functions before restarting the * process cycle. This will cause a gap in the audio flow, so it * should only be done at appropriate stopping points. * * @see jack_set_buffer_size_callback() * * @param client pointer to JACK client structure. * @param nframes new buffer size. Must be a power of two. * * @return 0 on success, otherwise a non-zero error code */ int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the sample rate of the jack system, as set by the user when * jackd was started. */ jack_nframes_t jack_get_sample_rate (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the current maximum size that will ever be passed to the @a * process_callback. It should only be used *before* the client has * been activated. This size may change, clients that depend on it * must register a @a bufsize_callback so they will be notified if it * does. * * @see jack_set_buffer_size_callback() */ jack_nframes_t jack_get_buffer_size (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * Old-style interface to become the timebase for the entire JACK * subsystem. * * @deprecated This function still exists for compatibility with the * earlier transport interface, but it does nothing. Instead, see * transport.h and use jack_set_timebase_callback(). * * @return ENOSYS, function not implemented. */ int jack_engine_takeover_timebase (jack_client_t *) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * @return the current CPU load estimated by JACK. This is a running * average of the time it takes to execute a full process cycle for * all clients as a percentage of the real time available per cycle * determined by the buffer size and sample rate. */ float jack_cpu_load (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ /** * @defgroup PortFunctions Creating & manipulating ports * @{ */ /** * Create a new port for the client. This is an object used for moving * data of any type in or out of the client. Ports may be connected * in various ways. * * Each port has a short name. The port's full name contains the name * of the client concatenated with a colon (:) followed by its short * name. The jack_port_name_size() is the maximum length of this full * name. Exceeding that will cause the port registration to fail and * return NULL. * * The @a port_name must be unique among all ports owned by this client. * If the name is not unique, the registration will fail. * * All ports have a type, which may be any non-NULL and non-zero * length string, passed as an argument. Some port types are built * into the JACK API, currently only JACK_DEFAULT_AUDIO_TYPE. * * @param client pointer to JACK client structure. * @param port_name non-empty short name for the new port (not * including the leading @a "client_name:"). Must be unique. * @param port_type port type name. If longer than * jack_port_type_size(), only that many characters are significant. * @param flags @ref JackPortFlags bit mask. * @param buffer_size must be non-zero if this is not a built-in @a * port_type. Otherwise, it is ignored. * * @return jack_port_t pointer on success, otherwise NULL. */ jack_port_t * jack_port_register (jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove the port from the client, disconnecting any existing * connections. * * @return 0 on success, otherwise a non-zero error code */ int jack_port_unregister (jack_client_t *client, jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * This returns a pointer to the memory area associated with the * specified port. For an output port, it will be a memory area * that can be written to; for an input port, it will be an area * containing the data from the port's connection(s), or * zero-filled. if there are multiple inbound connections, the data * will be mixed appropriately. * * FOR OUTPUT PORTS ONLY : DEPRECATED in Jack 2.0 !! * --------------------------------------------------- * You may cache the value returned, but only between calls to * your "blocksize" callback. For this reason alone, you should * either never cache the return value or ensure you have * a "blocksize" callback and be sure to invalidate the cached * address from there. * * Caching output ports is DEPRECATED in Jack 2.0, due to some new optimization (like "pipelining"). * Port buffers have to be retrieved in each callback for proper functionning. */ void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the UUID of the jack_port_t * * @see jack_uuid_to_string() to convert into a string representation */ jack_uuid_t jack_port_uuid (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the full name of the jack_port_t (including the @a * "client_name:" prefix). * * @see jack_port_name_size(). */ const char * jack_port_name (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the short name of the jack_port_t (not including the @a * "client_name:" prefix). * * @see jack_port_name_size(). */ const char * jack_port_short_name (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @ref JackPortFlags of the jack_port_t. */ int jack_port_flags (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @a port type, at most jack_port_type_size() characters * including a final NULL. */ const char * jack_port_type (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @a port type id. */ jack_port_type_id_t jack_port_type_id (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if the jack_port_t belongs to the jack_client_t. */ int jack_port_is_mine (const jack_client_t *client, const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return number of connections to or from @a port. * * @pre The calling client must own @a port. */ int jack_port_connected (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if the locally-owned @a port is @b directly connected * to the @a port_name. * * @see jack_port_name_size() */ int jack_port_connected_to (const jack_port_t *port, const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return a null-terminated array of full port names to which the @a * port is connected. If none, returns NULL. * * The caller is responsible for calling jack_free() on any non-NULL * returned value. * * @param port locally owned jack_port_t pointer. * * @see jack_port_name_size(), jack_port_get_all_connections() */ const char ** jack_port_get_connections (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return a null-terminated array of full port names to which the @a * port is connected. If none, returns NULL. * * The caller is responsible for calling jack_free() on any non-NULL * returned value. * * This differs from jack_port_get_connections() in two important * respects: * * 1) You may not call this function from code that is * executed in response to a JACK event. For example, * you cannot use it in a GraphReordered handler. * * 2) You need not be the owner of the port to get information * about its connections. * * @see jack_port_name_size() */ const char ** jack_port_get_all_connections (const jack_client_t *client, const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * * @deprecated This function will be removed from a future version * of JACK. Do not use it. There is no replacement. It has * turned out to serve essentially no purpose in real-life * JACK clients. */ int jack_port_tie (jack_port_t *src, jack_port_t *dst) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * * @deprecated This function will be removed from a future version * of JACK. Do not use it. There is no replacement. It has * turned out to serve essentially no purpose in real-life * JACK clients. */ int jack_port_untie (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * \bold THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED IN * NEW JACK CLIENTS * * Modify a port's short name. May be called at any time. If the * resulting full name (including the @a "client_name:" prefix) is * longer than jack_port_name_size(), it will be truncated. * * @return 0 on success, otherwise a non-zero error code. */ int jack_port_set_name (jack_port_t *port, const char *port_name) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Modify a port's short name. May NOT be called from a callback handling a server event. * If the resulting full name (including the @a "client_name:" prefix) is * longer than jack_port_name_size(), it will be truncated. * * @return 0 on success, otherwise a non-zero error code. * * This differs from jack_port_set_name() by triggering PortRename notifications to * clients that have registered a port rename handler. */ int jack_port_rename (jack_client_t* client, jack_port_t *port, const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * Set @a alias as an alias for @a port. May be called at any time. * If the alias is longer than jack_port_name_size(), it will be truncated. * * After a successful call, and until JACK exits or * @function jack_port_unset_alias() is called, @alias may be * used as a alternate name for the port. * * Ports can have up to two aliases - if both are already * set, this function will return an error. * * @return 0 on success, otherwise a non-zero error code. */ int jack_port_set_alias (jack_port_t *port, const char *alias) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove @a alias as an alias for @a port. May be called at any time. * * After a successful call, @a alias can no longer be * used as a alternate name for the port. * * @return 0 on success, otherwise a non-zero error code. */ int jack_port_unset_alias (jack_port_t *port, const char *alias) JACK_OPTIONAL_WEAK_EXPORT; /** * Get any aliases known for @port. * * @return the number of aliases discovered for the port */ int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for this @a port, turn input * monitoring on or off. Otherwise, do nothing. */ int jack_port_request_monitor (jack_port_t *port, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for this @a port_name, turn input * monitoring on or off. Otherwise, do nothing. * * @return 0 on success, otherwise a non-zero error code. * * @see jack_port_name_size() */ int jack_port_request_monitor_by_name (jack_client_t *client, const char *port_name, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for a port, this function turns * on input monitoring if it was off, and turns it off if only one * request has been made to turn it on. Otherwise it does nothing. * * @return 0 on success, otherwise a non-zero error code */ int jack_port_ensure_monitor (jack_port_t *port, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if input monitoring has been requested for @a port. */ int jack_port_monitoring_input (jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * Establish a connection between two ports. * * When a connection exists, data written to the source port will * be available to be read at the destination port. * * @pre The port types must be identical. * * @pre The @ref JackPortFlags of the @a source_port must include @ref * JackPortIsOutput. * * @pre The @ref JackPortFlags of the @a destination_port must include * @ref JackPortIsInput. * * @return 0 on success, EEXIST if the connection is already made, * otherwise a non-zero error code */ int jack_connect (jack_client_t *client, const char *source_port, const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove a connection between two ports. * * @pre The port types must be identical. * * @pre The @ref JackPortFlags of the @a source_port must include @ref * JackPortIsOutput. * * @pre The @ref JackPortFlags of the @a destination_port must include * @ref JackPortIsInput. * * @return 0 on success, otherwise a non-zero error code */ int jack_disconnect (jack_client_t *client, const char *source_port, const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT; /** * Perform the same function as jack_disconnect() using port handles * rather than names. This avoids the name lookup inherent in the * name-based version. * * Clients connecting their own ports are likely to use this function, * while generic connection clients (e.g. patchbays) would use * jack_disconnect(). */ int jack_port_disconnect (jack_client_t *client, jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a full JACK port name * including the final NULL character. This value is a constant. * * A port's full name contains the owning client name concatenated * with a colon (:) followed by its short name and a NULL * character. */ int jack_port_name_size(void) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a JACK port type name * including the final NULL character. This value is a constant. */ int jack_port_type_size(void) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the buffersize of a port of type @arg port_type. * * this function may only be called in a buffer_size callback. */ size_t jack_port_type_get_buffer_size (jack_client_t *client, const char *port_type) JACK_WEAK_EXPORT; /*@}*/ /** * @defgroup LatencyFunctions Managing and determining latency * * The purpose of JACK's latency API is to allow clients to * easily answer two questions: * * - How long has it been since the data read from a port arrived * at the edge of the JACK graph (either via a physical port * or being synthesized from scratch)? * * - How long will it be before the data written to a port arrives * at the edge of a JACK graph? * To help answering these two questions, all JACK ports have two * latency values associated with them, both measured in frames: * * capture latency: how long since the data read from * the buffer of a port arrived at * a port marked with JackPortIsTerminal. * The data will have come from the "outside * world" if the terminal port is also * marked with JackPortIsPhysical, or * will have been synthesized by the client * that owns the terminal port. * * playback latency: how long until the data * written to the buffer of port will reach a port * marked with JackPortIsTerminal. * * Both latencies might potentially have more than one value * because there may be multiple pathways to/from a given port * and a terminal port. Latency is therefore generally * expressed a min/max pair. * * In most common setups, the minimum and maximum latency * are the same, but this design accomodates more complex * routing, and allows applications (and thus users) to * detect cases where routing is creating an anomalous * situation that may either need fixing or more * sophisticated handling by clients that care about * latency. * * See also @ref jack_set_latency_callback for details on how * clients that add latency to the signal path should interact * with JACK to ensure that the correct latency figures are * used. * @{ */ /** * The port latency is zero by default. Clients that control * physical hardware with non-zero latency should call this * to set the latency to its correct value. Note that the value * should include any systemic latency present "outside" the * physical hardware controlled by the client. For example, * for a client controlling a digital audio interface connected * to an external digital converter, the latency setting should * include both buffering by the audio interface *and* the converter. * * @deprecated This method will be removed in the next major * release of JACK. It should not be used in new code, and should * be replaced by a latency callback that calls @ref * jack_port_set_latency_range(). */ void jack_port_set_latency (jack_port_t *port, jack_nframes_t) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * return the latency range defined by @a mode for * @a port, in frames. * * See @ref LatencyFunctions for the definition of each latency value. * * This is normally used in the LatencyCallback. * and therefor safe to execute from callbacks. */ void jack_port_get_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; /** * set the minimum and maximum latencies defined by * @a mode for @a port, in frames. * * See @ref LatencyFunctions for the definition of each latency value. * * This function should ONLY be used inside a latency * callback. The client should determine the current * value of the latency using @ref jack_port_get_latency_range() * (called using the same mode as @a mode) * and then add some number of frames to that reflects * latency added by the client. * * How much latency a client adds will vary * dramatically. For most clients, the answer is zero * and there is no reason for them to register a latency * callback and thus they should never call this * function. * * More complex clients that take an input signal, * transform it in some way and output the result but * not during the same process() callback will * generally know a single constant value to add * to the value returned by @ref jack_port_get_latency_range(). * * Such clients would register a latency callback (see * @ref jack_set_latency_callback) and must know what input * ports feed which output ports as part of their * internal state. Their latency callback will update * the ports' latency values appropriately. * * A pseudo-code example will help. The @a mode argument to the latency * callback will determine whether playback or capture * latency is being set. The callback will use * @ref jack_port_set_latency_range() as follows: * * \code * jack_latency_range_t range; * if (mode == JackPlaybackLatency) { * foreach input_port in (all self-registered port) { * jack_port_get_latency_range (port_feeding_input_port, JackPlaybackLatency, &range); * range.min += min_delay_added_as_signal_flows_from port_feeding to input_port; * range.max += max_delay_added_as_signal_flows_from port_feeding to input_port; * jack_port_set_latency_range (input_port, JackPlaybackLatency, &range); * } * } else if (mode == JackCaptureLatency) { * foreach output_port in (all self-registered port) { * jack_port_get_latency_range (port_fed_by_output_port, JackCaptureLatency, &range); * range.min += min_delay_added_as_signal_flows_from_output_port_to_fed_by_port; * range.max += max_delay_added_as_signal_flows_from_output_port_to_fed_by_port; * jack_port_set_latency_range (output_port, JackCaptureLatency, &range); * } * } * \endcode * * In this relatively simple pseudo-code example, it is assumed that * each input port or output is connected to only 1 output or input * port respectively. * * If a port is connected to more than 1 other port, then the * range.min and range.max values passed to @ref * jack_port_set_latency_range() should reflect the minimum and * maximum values across all connected ports. * * See the description of @ref jack_set_latency_callback for more * information. */ void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; /** * Request a complete recomputation of all port latencies. This * can be called by a client that has just changed the internal * latency of its port using jack_port_set_latency * and wants to ensure that all signal pathways in the graph * are updated with respect to the values that will be returned * by jack_port_get_total_latency. It allows a client * to change multiple port latencies without triggering a * recompute for each change. * * @return zero for successful execution of the request. non-zero * otherwise. */ int jack_recompute_total_latencies (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the time (in frames) between data being available or * delivered at/to a port, and the time at which it arrived at or is * delivered to the "other side" of the port. E.g. for a physical * audio output port, this is the time between writing to the port and * when the signal will leave the connector. For a physical audio * input port, this is the time between the sound arriving at the * connector and the corresponding frames being readable from the * port. * * @deprecated This method will be removed in the next major * release of JACK. It should not be used in new code, and should * be replaced by jack_port_get_latency_range() in any existing * use cases. */ jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * The maximum of the sum of the latencies in every * connection path that can be drawn between the port and other * ports with the @ref JackPortIsTerminal flag set. * * @deprecated This method will be removed in the next major * release of JACK. It should not be used in new code, and should * be replaced by jack_port_get_latency_range() in any existing * use cases. */ jack_nframes_t jack_port_get_total_latency (jack_client_t *client, jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Request a complete recomputation of a port's total latency. This * can be called by a client that has just changed the internal * latency of its port using jack_port_set_latency * and wants to ensure that all signal pathways in the graph * are updated with respect to the values that will be returned * by jack_port_get_total_latency. * * @return zero for successful execution of the request. non-zero * otherwise. * * @deprecated This method will be removed in the next major * release of JACK. It should not be used in new code, and should * be replaced by jack_recompute_total_latencies() in any existing * use cases. */ int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /*@}*/ /** * @defgroup PortSearching Looking up ports * @{ */ /** * @param port_name_pattern A regular expression used to select * ports by name. If NULL or of zero length, no selection based * on name will be carried out. * @param type_name_pattern A regular expression used to select * ports by type. If NULL or of zero length, no selection based * on type will be carried out. * @param flags A value used to select ports by their flags. * If zero, no selection based on flags will be carried out. * * @return a NULL-terminated array of ports that match the specified * arguments. The caller is responsible for calling jack_free() any * non-NULL returned value. * * @see jack_port_name_size(), jack_port_type_size() */ const char ** jack_get_ports (jack_client_t *client, const char *port_name_pattern, const char *type_name_pattern, unsigned long flags) JACK_OPTIONAL_WEAK_EXPORT; /** * @return address of the jack_port_t named @a port_name. * * @see jack_port_name_size() */ jack_port_t * jack_port_by_name (jack_client_t *client, const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return address of the jack_port_t of a @a port_id. */ jack_port_t * jack_port_by_id (jack_client_t *client, jack_port_id_t port_id) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ /** * @defgroup TimeFunctions Handling time * @{ * * JACK time is in units of 'frames', according to the current sample rate. * The absolute value of frame times is meaningless, frame times have meaning * only relative to each other. */ /** * @return the estimated time in frames that has passed since the JACK * server began the current process cycle. */ jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated current time in frames. * This function is intended for use in other threads (not the process * callback). The return value can be compared with the value of * jack_last_frame_time to relate time in other threads to JACK time. */ jack_nframes_t jack_frame_time (const jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the precise time at the start of the current process cycle. * This function may only be used from the process callback, and can * be used to interpret timestamps generated by jack_frame_time() in * other threads with respect to the current process cycle. * * This is the only jack time function that returns exact time: * when used during the process callback it always returns the same * value (until the next process callback, where it will return * that value + nframes, etc). The return value is guaranteed to be * monotonic and linear in this fashion unless an xrun occurs. * If an xrun occurs, clients must check this value again, as time * may have advanced in a non-linear way (e.g. cycles may have been skipped). */ jack_nframes_t jack_last_frame_time (const jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * This function may only be used from the process callback. * It provides the internal cycle timing information as used by * most of the other time related functions. This allows the * caller to map between frame counts and microseconds with full * precision (i.e. without rounding frame times to integers), * and also provides e.g. the microseconds time of the start of * the current cycle directly (it has to be computed otherwise). * * If the return value is zero, the following information is * provided in the variables pointed to by the arguments: * * current_frames: the frame time counter at the start of the * current cycle, same as jack_last_frame_time(). * current_usecs: the microseconds time at the start of the * current cycle. * next_usecs: the microseconds time of the start of the next * next cycle as computed by the DLL. * period_usecs: the current best estimate of the period time in * microseconds. * * NOTES: * * Because of the types used, all the returned values except period_usecs * are unsigned. In computations mapping between frames and microseconds * *signed* differences are required. The easiest way is to compute those * separately and assign them to the appropriate signed variables, * int32_t for frames and int64_t for usecs. See the implementation of * jack_frames_to_time() and Jack_time_to_frames() for an example. * * Unless there was an xrun, skipped cycles, or the current cycle is the * first after freewheeling or starting Jack, the value of current_usecs * will always be the value of next_usecs of the previous cycle. * * The value of period_usecs will in general NOT be exactly equal to * the difference of next_usecs and current_usecs. This is because to * ensure stability of the DLL and continuity of the mapping, a fraction * of the loop error must be included in next_usecs. For an accurate * mapping between frames and microseconds, the difference of next_usecs * and current_usecs should be used, and not period_usecs. * * @return zero if OK, non-zero otherwise. */ int jack_get_cycle_times(const jack_client_t *client, jack_nframes_t *current_frames, jack_time_t *current_usecs, jack_time_t *next_usecs, float *period_usecs) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated time in microseconds of the specified frame time */ jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated time in frames for the specified system time. */ jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return return JACK's current system time in microseconds, * using the JACK clock source. * * The value returned is guaranteed to be monotonic, but not linear. */ jack_time_t jack_get_time(void) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ /** * @defgroup ErrorOutput Controlling error/information output */ /*@{*/ /** * Display JACK error message. * * Set via jack_set_error_function(), otherwise a JACK-provided * default will print @a msg (plus a newline) to stderr. * * @param msg error message text (no newline at end). */ extern void (*jack_error_callback)(const char *msg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the @ref jack_error_callback for error message display. * Set it to NULL to restore default_jack_error_callback function. * * The JACK library provides two built-in callbacks for this purpose: * default_jack_error_callback() and silent_jack_error_callback(). */ void jack_set_error_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXPORT; /** * Display JACK info message. * * Set via jack_set_info_function(), otherwise a JACK-provided * default will print @a msg (plus a newline) to stdout. * * @param msg info message text (no newline at end). */ extern void (*jack_info_callback)(const char *msg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the @ref jack_info_callback for info message display. * Set it to NULL to restore default_jack_info_callback function. * * The JACK library provides two built-in callbacks for this purpose: * default_jack_info_callback() and silent_jack_info_callback(). */ void jack_set_info_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ /** * The free function to be used on memory returned by jack_port_get_connections, * jack_port_get_all_connections, jack_get_ports and jack_get_internal_client_name functions. * This is MANDATORY on Windows when otherwise all nasty runtime version related crashes can occur. * Developers are strongly encouraged to use this function instead of the standard "free" function in new code. * * @param ptr the memory pointer to be deallocated. */ void jack_free(void* ptr) JACK_OPTIONAL_WEAK_EXPORT; #ifdef __cplusplus } #endif #endif /* __jack_h__ */ 1.9.12~dfsg/common/jack/weakmacros.h0000644000000000000000000000531213214314510016046 0ustar rootroot/* Copyright (C) 2010 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __weakmacros_h__ #define __weakmacros_h__ /************************************************************* * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function * added to the JACK API after the 0.116.2 release. * * Functions that predate this release are marked with * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile * time in a variety of ways. The default definition is empty, * so that these symbols get normal linkage. If you wish to * use all JACK symbols with weak linkage, include * before jack.h. *************************************************************/ #ifdef __APPLE__ #define WEAK_ATTRIBUTE weak_import #else #define WEAK_ATTRIBUTE __weak__ #endif #ifndef JACK_WEAK_EXPORT #ifdef __GNUC__ /* JACK_WEAK_EXPORT needs to be a macro which expands into a compiler directive. If non-null, the directive must tell the compiler to arrange for weak linkage of the symbol it used with. For this to work full may require linker arguments in the client as well. */ #ifdef _WIN32 /* Not working with __declspec(dllexport) so normal linking Linking with JackWeakAPI.cpp will be the preferred way. */ #define JACK_WEAK_EXPORT #else #define JACK_WEAK_EXPORT __attribute__((WEAK_ATTRIBUTE)) #endif #else /* Add other things here for non-gcc platforms */ #ifdef _WIN32 #define JACK_WEAK_EXPORT #endif #endif #endif #ifndef JACK_WEAK_EXPORT #define JACK_WEAK_EXPORT #endif #ifndef JACK_OPTIONAL_WEAK_EXPORT #define JACK_OPTIONAL_WEAK_EXPORT #endif #ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT #ifdef __GNUC__ #define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((__deprecated__)) #else /* Add other things here for non-gcc platforms */ #ifdef _WIN32 #define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT #endif #endif /* __GNUC__ */ #ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT #define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT #endif #endif #endif /* __weakmacros_h__ */ 1.9.12~dfsg/common/jack/transport.h0000644000000000000000000002070413214314510015750 0ustar rootroot/* Copyright (C) 2002 Paul Davis Copyright (C) 2003 Jack O'Quin This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_transport_h__ #define __jack_transport_h__ #ifdef __cplusplus extern "C" { #endif #include #include /** * @defgroup TransportControl Transport and Timebase control * @{ */ /** * Called by the timebase master to release itself from that * responsibility. * * If the timebase master releases the timebase or leaves the JACK * graph for any reason, the JACK engine takes over at the start of * the next process cycle. The transport state does not change. If * rolling, it continues to play, with frame numbers as the only * available position information. * * @see jack_set_timebase_callback * * @param client the JACK client structure. * * @return 0 on success, otherwise a non-zero error code. */ int jack_release_timebase (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Register (or unregister) as a slow-sync client, one that cannot * respond immediately to transport position changes. * * The @a sync_callback will be invoked at the first available * opportunity after its registration is complete. If the client is * currently active this will be the following process cycle, * otherwise it will be the first cycle after calling jack_activate(). * After that, it runs according to the ::JackSyncCallback rules. * Clients that don't set a @a sync_callback are assumed to be ready * immediately any time the transport wants to start. * * @param client the JACK client structure. * @param sync_callback is a realtime function that returns TRUE when * the client is ready. Setting @a sync_callback to NULL declares that * this client no longer requires slow-sync processing. * @param arg an argument for the @a sync_callback function. * * @return 0 on success, otherwise a non-zero error code. */ int jack_set_sync_callback (jack_client_t *client, JackSyncCallback sync_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the timeout value for slow-sync clients. * * This timeout prevents unresponsive slow-sync clients from * completely halting the transport mechanism. The default is two * seconds. When the timeout expires, the transport starts rolling, * even if some slow-sync clients are still unready. The @a * sync_callbacks of these clients continue being invoked, giving them * a chance to catch up. * * @see jack_set_sync_callback * * @param client the JACK client structure. * @param timeout is delay (in microseconds) before the timeout expires. * * @return 0 on success, otherwise a non-zero error code. */ int jack_set_sync_timeout (jack_client_t *client, jack_time_t timeout) JACK_OPTIONAL_WEAK_EXPORT; /** * Register as timebase master for the JACK subsystem. * * The timebase master registers a callback that updates extended * position information such as beats or timecode whenever necessary. * Without this extended information, there is no need for this * function. * * There is never more than one master at a time. When a new client * takes over, the former @a timebase_callback is no longer called. * Taking over the timebase may be done conditionally, so it fails if * there was a master already. * * @param client the JACK client structure. * @param conditional non-zero for a conditional request. * @param timebase_callback is a realtime function that returns * position information. * @param arg an argument for the @a timebase_callback function. * * @return * - 0 on success; * - EBUSY if a conditional request fails because there was already a * timebase master; * - other non-zero error code. */ int jack_set_timebase_callback (jack_client_t *client, int conditional, JackTimebaseCallback timebase_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Reposition the transport to a new frame number. * * May be called at any time by any client. The new position takes * effect in two process cycles. If there are slow-sync clients and * the transport is already rolling, it will enter the * ::JackTransportStarting state and begin invoking their @a * sync_callbacks until ready. This function is realtime-safe. * * @see jack_transport_reposition, jack_set_sync_callback * * @param client the JACK client structure. * @param frame frame number of new transport position. * * @return 0 if valid request, non-zero otherwise. */ int jack_transport_locate (jack_client_t *client, jack_nframes_t frame) JACK_OPTIONAL_WEAK_EXPORT; /** * Query the current transport state and position. * * This function is realtime-safe, and can be called from any thread. * If called from the process thread, @a pos corresponds to the first * frame of the current cycle and the state returned is valid for the * entire cycle. * * @param client the JACK client structure. * @param pos pointer to structure for returning current transport * position; @a pos->valid will show which fields contain valid data. * If @a pos is NULL, do not return position information. * * @return Current transport state. */ jack_transport_state_t jack_transport_query (const jack_client_t *client, jack_position_t *pos) JACK_OPTIONAL_WEAK_EXPORT; /** * Return an estimate of the current transport frame, * including any time elapsed since the last transport * positional update. * * @param client the JACK client structure */ jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Request a new transport position. * * May be called at any time by any client. The new position takes * effect in two process cycles. If there are slow-sync clients and * the transport is already rolling, it will enter the * ::JackTransportStarting state and begin invoking their @a * sync_callbacks until ready. This function is realtime-safe. * * @see jack_transport_locate, jack_set_sync_callback * * @param client the JACK client structure. * @param pos requested new transport position. * * @return 0 if valid request, EINVAL if position structure rejected. */ int jack_transport_reposition (jack_client_t *client, const jack_position_t *pos) JACK_OPTIONAL_WEAK_EXPORT; /** * Start the JACK transport rolling. * * Any client can make this request at any time. It takes effect no * sooner than the next process cycle, perhaps later if there are * slow-sync clients. This function is realtime-safe. * * @see jack_set_sync_callback * * @param client the JACK client structure. */ void jack_transport_start (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Stop the JACK transport. * * Any client can make this request at any time. It takes effect on * the next process cycle. This function is realtime-safe. * * @param client the JACK client structure. */ void jack_transport_stop (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Gets the current transport info structure (deprecated). * * @param client the JACK client structure. * @param tinfo current transport info structure. The "valid" field * describes which fields contain valid data. * * @deprecated This is for compatibility with the earlier transport * interface. Use jack_transport_query(), instead. * * @pre Must be called from the process thread. */ void jack_get_transport_info (jack_client_t *client, jack_transport_info_t *tinfo) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the transport info structure (deprecated). * * @deprecated This function still exists for compatibility with the * earlier transport interface, but it does nothing. Instead, define * a ::JackTimebaseCallback. */ void jack_set_transport_info (jack_client_t *client, jack_transport_info_t *tinfo) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ #ifdef __cplusplus } #endif #endif /* __jack_transport_h__ */ 1.9.12~dfsg/common/jack/uuid.h0000644000000000000000000000315513214314510014663 0ustar rootroot/* Copyright (C) 2013 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_uuid_h__ #define __jack_uuid_h__ #include #ifdef __cplusplus extern "C" { #endif #define JACK_UUID_SIZE 36 #define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */ #define JACK_UUID_EMPTY_INITIALIZER 0 extern jack_uuid_t jack_client_uuid_generate (); extern jack_uuid_t jack_port_uuid_generate (uint32_t port_id); extern uint32_t jack_uuid_to_index (jack_uuid_t); extern int jack_uuid_compare (jack_uuid_t, jack_uuid_t); extern void jack_uuid_copy (jack_uuid_t* dst, jack_uuid_t src); extern void jack_uuid_clear (jack_uuid_t*); extern int jack_uuid_parse (const char *buf, jack_uuid_t*); extern void jack_uuid_unparse (jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]); extern int jack_uuid_empty (jack_uuid_t); #ifdef __cplusplus } /* namespace */ #endif #endif /* __jack_uuid_h__ */ 1.9.12~dfsg/common/jack/types.h0000644000000000000000000005766313214314510015076 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Jack O'Quin This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_types_h__ #define __jack_types_h__ #include typedef uint64_t jack_uuid_t; typedef int32_t jack_shmsize_t; /** * Type used to represent sample frame counts. */ typedef uint32_t jack_nframes_t; /** * Maximum value that can be stored in jack_nframes_t */ #define JACK_MAX_FRAMES (4294967295U) /* This should be UINT32_MAX, but C++ has a problem with that. */ /** * Type used to represent the value of free running * monotonic clock with units of microseconds. */ typedef uint64_t jack_time_t; /** * Maximum size of @a load_init string passed to an internal client * jack_initialize() function via jack_internal_client_load(). */ #define JACK_LOAD_INIT_LIMIT 1024 /** * jack_intclient_t is an opaque type representing a loaded internal * client. You may only access it using the API provided in @ref * intclient.h "". */ typedef uint64_t jack_intclient_t; /** * jack_port_t is an opaque type. You may only access it using the * API provided. */ typedef struct _jack_port jack_port_t; /** * jack_client_t is an opaque type. You may only access it using the * API provided. */ typedef struct _jack_client jack_client_t; /** * Ports have unique ids. A port registration callback is the only * place you ever need to know their value. */ typedef uint32_t jack_port_id_t; typedef uint32_t jack_port_type_id_t; /** * @ref jack_options_t bits */ enum JackOptions { /** * Null value to use when no option bits are needed. */ JackNullOption = 0x00, /** * Do not automatically start the JACK server when it is not * already running. This option is always selected if * \$JACK_NO_START_SERVER is defined in the calling process * environment. */ JackNoStartServer = 0x01, /** * Use the exact client name requested. Otherwise, JACK * automatically generates a unique one, if needed. */ JackUseExactName = 0x02, /** * Open with optional (char *) server_name parameter. */ JackServerName = 0x04, /** * Load internal client from optional (char *) * load_name. Otherwise use the @a client_name. */ JackLoadName = 0x08, /** * Pass optional (char *) load_init string to the * jack_initialize() entry point of an internal client. */ JackLoadInit = 0x10, /** * pass a SessionID Token this allows the sessionmanager to identify the client again. */ JackSessionID = 0x20 }; /** Valid options for opening an external client. */ #define JackOpenOptions (JackSessionID|JackServerName|JackNoStartServer|JackUseExactName) /** Valid options for loading an internal client. */ #define JackLoadOptions (JackLoadInit|JackLoadName|JackUseExactName) /** * Options for several JACK operations, formed by OR-ing together the * relevant @ref JackOptions bits. */ typedef enum JackOptions jack_options_t; /** * @ref jack_status_t bits */ enum JackStatus { /** * Overall operation failed. */ JackFailure = 0x01, /** * The operation contained an invalid or unsupported option. */ JackInvalidOption = 0x02, /** * The desired client name was not unique. With the @ref * JackUseExactName option this situation is fatal. Otherwise, * the name was modified by appending a dash and a two-digit * number in the range "-01" to "-99". The * jack_get_client_name() function will return the exact string * that was used. If the specified @a client_name plus these * extra characters would be too long, the open fails instead. */ JackNameNotUnique = 0x04, /** * The JACK server was started as a result of this operation. * Otherwise, it was running already. In either case the caller * is now connected to jackd, so there is no race condition. * When the server shuts down, the client will find out. */ JackServerStarted = 0x08, /** * Unable to connect to the JACK server. */ JackServerFailed = 0x10, /** * Communication error with the JACK server. */ JackServerError = 0x20, /** * Requested client does not exist. */ JackNoSuchClient = 0x40, /** * Unable to load internal client */ JackLoadFailure = 0x80, /** * Unable to initialize client */ JackInitFailure = 0x100, /** * Unable to access shared memory */ JackShmFailure = 0x200, /** * Client's protocol version does not match */ JackVersionError = 0x400, /** * Backend error */ JackBackendError = 0x800, /** * Client zombified failure */ JackClientZombie = 0x1000 }; /** * Status word returned from several JACK operations, formed by * OR-ing together the relevant @ref JackStatus bits. */ typedef enum JackStatus jack_status_t; /** * @ref jack_latency_callback_mode_t */ enum JackLatencyCallbackMode { /** * Latency Callback for Capture Latency. * Input Ports have their latency value setup. * In the Callback the client needs to set the latency of the output ports */ JackCaptureLatency, /** * Latency Callback for Playback Latency. * Output Ports have their latency value setup. * In the Callback the client needs to set the latency of the input ports */ JackPlaybackLatency }; /** * Type of Latency Callback (Capture or Playback) */ typedef enum JackLatencyCallbackMode jack_latency_callback_mode_t; /** * Prototype for the client supplied function that is called * by the engine when port latencies need to be recalculated * * @param mode playback or capture latency * @param arg pointer to a client supplied data * * @return zero on success, non-zero on error */ typedef void (*JackLatencyCallback)(jack_latency_callback_mode_t mode, void *arg); /** * the new latency API operates on Ranges. */ PRE_PACKED_STRUCTURE struct _jack_latency_range { /** * minimum latency */ jack_nframes_t min; /** * maximum latency */ jack_nframes_t max; } POST_PACKED_STRUCTURE; typedef struct _jack_latency_range jack_latency_range_t; /** * Prototype for the client supplied function that is called * by the engine anytime there is work to be done. * * @pre nframes == jack_get_buffer_size() * @pre nframes == pow(2,x) * * @param nframes number of frames to process * @param arg pointer to a client supplied structure * * @return zero on success, non-zero on error */ typedef int (*JackProcessCallback)(jack_nframes_t nframes, void *arg); /** * Prototype for the client thread routine called * by the engine when the client is inserted in the graph. * * @param arg pointer to a client supplied structure * */ typedef void *(*JackThreadCallback)(void* arg); /** * Prototype for the client supplied function that is called * once after the creation of the thread in which other * callbacks will be made. Special thread characteristics * can be set from this callback, for example. This is a * highly specialized callback and most clients will not * and should not use it. * * @param arg pointer to a client supplied structure * * @return void */ typedef void (*JackThreadInitCallback)(void *arg); /** * Prototype for the client supplied function that is called * whenever the processing graph is reordered. * * @param arg pointer to a client supplied structure * * @return zero on success, non-zero on error */ typedef int (*JackGraphOrderCallback)(void *arg); /** * Prototype for the client-supplied function that is called whenever * an xrun has occured. * * @see jack_get_xrun_delayed_usecs() * * @param arg pointer to a client supplied structure * * @return zero on success, non-zero on error */ typedef int (*JackXRunCallback)(void *arg); /** * Prototype for the @a bufsize_callback that is invoked whenever the * JACK engine buffer size changes. Although this function is called * in the JACK process thread, the normal process cycle is suspended * during its operation, causing a gap in the audio flow. So, the @a * bufsize_callback can allocate storage, touch memory not previously * referenced, and perform other operations that are not realtime * safe. * * @param nframes buffer size * @param arg pointer supplied by jack_set_buffer_size_callback(). * * @return zero on success, non-zero on error */ typedef int (*JackBufferSizeCallback)(jack_nframes_t nframes, void *arg); /** * Prototype for the client supplied function that is called * when the engine sample rate changes. * * @param nframes new engine sample rate * @param arg pointer to a client supplied structure * * @return zero on success, non-zero on error */ typedef int (*JackSampleRateCallback)(jack_nframes_t nframes, void *arg); /** * Prototype for the client supplied function that is called * whenever a port is registered or unregistered. * * @param port the ID of the port * @param arg pointer to a client supplied data * @param register non-zero if the port is being registered, * zero if the port is being unregistered */ typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int /* register */, void *arg); /** * Prototype for the client supplied function that is called * whenever a client is registered or unregistered. * * @param name a null-terminated string containing the client name * @param register non-zero if the client is being registered, * zero if the client is being unregistered * @param arg pointer to a client supplied structure */ typedef void (*JackClientRegistrationCallback)(const char* name, int /* register */, void *arg); /** * Prototype for the client supplied function that is called * whenever a port is connected or disconnected. * * @param a one of two ports connected or disconnected * @param b one of two ports connected or disconnected * @param connect non-zero if ports were connected * zero if ports were disconnected * @param arg pointer to a client supplied data */ typedef void (*JackPortConnectCallback)(jack_port_id_t a, jack_port_id_t b, int connect, void* arg); /** * Prototype for the client supplied function that is called * whenever the port name has been changed. * * @param port the port that has been renamed * @param new_name the new name * @param arg pointer to a client supplied structure */ typedef void (*JackPortRenameCallback)(jack_port_id_t port, const char* old_name, const char* new_name, void *arg); /** * Prototype for the client supplied function that is called * whenever jackd starts or stops freewheeling. * * @param starting non-zero if we start starting to freewheel, zero otherwise * @param arg pointer to a client supplied structure */ typedef void (*JackFreewheelCallback)(int starting, void *arg); /** * Prototype for the client supplied function that is called * whenever jackd is shutdown. Note that after server shutdown, * the client pointer is *not* deallocated by libjack, * the application is responsible to properly use jack_client_close() * to release client ressources. Warning: jack_client_close() cannot be * safely used inside the shutdown callback and has to be called outside of * the callback context. * * @param arg pointer to a client supplied structure */ typedef void (*JackShutdownCallback)(void *arg); /** * Prototype for the client supplied function that is called * whenever jackd is shutdown. Note that after server shutdown, * the client pointer is *not* deallocated by libjack, * the application is responsible to properly use jack_client_close() * to release client ressources. Warning: jack_client_close() cannot be * safely used inside the shutdown callback and has to be called outside of * the callback context. * @param code a status word, formed by OR-ing together the relevant @ref JackStatus bits. * @param reason a string describing the shutdown reason (backend failure, server crash... etc...). * Note that this string will not be available anymore after the callback returns, so possibly copy it. * @param arg pointer to a client supplied structure */ typedef void (*JackInfoShutdownCallback)(jack_status_t code, const char* reason, void *arg); /** * Used for the type argument of jack_port_register() for default * audio ports and midi ports. */ #define JACK_DEFAULT_AUDIO_TYPE "32 bit float mono audio" #define JACK_DEFAULT_MIDI_TYPE "8 bit raw midi" /** * For convenience, use this typedef if you want to be able to change * between float and double. You may want to typedef sample_t to * jack_default_audio_sample_t in your application. */ typedef float jack_default_audio_sample_t; /** * A port has a set of flags that are formed by AND-ing together the * desired values from the list below. The flags "JackPortIsInput" and * "JackPortIsOutput" are mutually exclusive and it is an error to use * them both. */ enum JackPortFlags { /** * if JackPortIsInput is set, then the port can receive * data. */ JackPortIsInput = 0x1, /** * if JackPortIsOutput is set, then data can be read from * the port. */ JackPortIsOutput = 0x2, /** * if JackPortIsPhysical is set, then the port corresponds * to some kind of physical I/O connector. */ JackPortIsPhysical = 0x4, /** * if JackPortCanMonitor is set, then a call to * jack_port_request_monitor() makes sense. * * Precisely what this means is dependent on the client. A typical * result of it being called with TRUE as the second argument is * that data that would be available from an output port (with * JackPortIsPhysical set) is sent to a physical output connector * as well, so that it can be heard/seen/whatever. * * Clients that do not control physical interfaces * should never create ports with this bit set. */ JackPortCanMonitor = 0x8, /** * JackPortIsTerminal means: * * for an input port: the data received by the port * will not be passed on or made * available at any other port * * for an output port: the data available at the port * does not originate from any other port * * Audio synthesizers, I/O hardware interface clients, HDR * systems are examples of clients that would set this flag for * their ports. */ JackPortIsTerminal = 0x10, }; /** * Transport states. */ typedef enum { /* the order matters for binary compatibility */ JackTransportStopped = 0, /**< Transport halted */ JackTransportRolling = 1, /**< Transport playing */ JackTransportLooping = 2, /**< For OLD_TRANSPORT, now ignored */ JackTransportStarting = 3, /**< Waiting for sync ready */ JackTransportNetStarting = 4, /**< Waiting for sync ready on the network*/ } jack_transport_state_t; typedef uint64_t jack_unique_t; /**< Unique ID (opaque) */ /** * Optional struct jack_position_t fields. */ typedef enum { JackPositionBBT = 0x10, /**< Bar, Beat, Tick */ JackPositionTimecode = 0x20, /**< External timecode */ JackBBTFrameOffset = 0x40, /**< Frame offset of BBT information */ JackAudioVideoRatio = 0x80, /**< audio frames per video frame */ JackVideoFrameOffset = 0x100 /**< frame offset of first video frame */ } jack_position_bits_t; /** all valid position bits */ #define JACK_POSITION_MASK (JackPositionBBT|JackPositionTimecode) #define EXTENDED_TIME_INFO PRE_PACKED_STRUCTURE struct _jack_position { /* these four cannot be set from clients: the server sets them */ jack_unique_t unique_1; /**< unique ID */ jack_time_t usecs; /**< monotonic, free-rolling */ jack_nframes_t frame_rate; /**< current frame rate (per second) */ jack_nframes_t frame; /**< frame number, always present */ jack_position_bits_t valid; /**< which other fields are valid */ /* JackPositionBBT fields: */ int32_t bar; /**< current bar */ int32_t beat; /**< current beat-within-bar */ int32_t tick; /**< current tick-within-beat */ double bar_start_tick; float beats_per_bar; /**< time signature "numerator" */ float beat_type; /**< time signature "denominator" */ double ticks_per_beat; double beats_per_minute; /* JackPositionTimecode fields: (EXPERIMENTAL: could change) */ double frame_time; /**< current time in seconds */ double next_time; /**< next sequential frame_time (unless repositioned) */ /* JackBBTFrameOffset fields: */ jack_nframes_t bbt_offset; /**< frame offset for the BBT fields (the given bar, beat, and tick values actually refer to a time frame_offset frames before the start of the cycle), should be assumed to be 0 if JackBBTFrameOffset is not set. If JackBBTFrameOffset is set and this value is zero, the BBT time refers to the first frame of this cycle. If the value is positive, the BBT time refers to a frame that many frames before the start of the cycle. */ /* JACK video positional data (experimental) */ float audio_frames_per_video_frame; /**< number of audio frames per video frame. Should be assumed zero if JackAudioVideoRatio is not set. If JackAudioVideoRatio is set and the value is zero, no video data exists within the JACK graph */ jack_nframes_t video_offset; /**< audio frame at which the first video frame in this cycle occurs. Should be assumed to be 0 if JackVideoFrameOffset is not set. If JackVideoFrameOffset is set, but the value is zero, there is no video frame within this cycle. */ /* For binary compatibility, new fields should be allocated from * this padding area with new valid bits controlling access, so * the existing structure size and offsets are preserved. */ int32_t padding[7]; /* When (unique_1 == unique_2) the contents are consistent. */ jack_unique_t unique_2; /**< unique ID */ } POST_PACKED_STRUCTURE; typedef struct _jack_position jack_position_t; /** * Prototype for the @a sync_callback defined by slow-sync clients. * When the client is active, this callback is invoked just before * process() in the same thread. This occurs once after registration, * then subsequently whenever some client requests a new position, or * the transport enters the ::JackTransportStarting state. This * realtime function must not wait. * * The transport @a state will be: * * - ::JackTransportStopped when a new position is requested; * - ::JackTransportStarting when the transport is waiting to start; * - ::JackTransportRolling when the timeout has expired, and the * position is now a moving target. * * @param state current transport state. * @param pos new transport position. * @param arg the argument supplied by jack_set_sync_callback(). * * @return TRUE (non-zero) when ready to roll. */ typedef int (*JackSyncCallback)(jack_transport_state_t state, jack_position_t *pos, void *arg); /** * Prototype for the @a timebase_callback used to provide extended * position information. Its output affects all of the following * process cycle. This realtime function must not wait. * * This function is called immediately after process() in the same * thread whenever the transport is rolling, or when any client has * requested a new position in the previous cycle. The first cycle * after jack_set_timebase_callback() is also treated as a new * position, or the first cycle after jack_activate() if the client * had been inactive. * * The timebase master may not use its @a pos argument to set @a * pos->frame. To change position, use jack_transport_reposition() or * jack_transport_locate(). These functions are realtime-safe, the @a * timebase_callback can call them directly. * * @param state current transport state. * @param nframes number of frames in current period. * @param pos address of the position structure for the next cycle; @a * pos->frame will be its frame number. If @a new_pos is FALSE, this * structure contains extended position information from the current * cycle. If TRUE, it contains whatever was set by the requester. * The @a timebase_callback's task is to update the extended * information here. * @param new_pos TRUE (non-zero) for a newly requested @a pos, or for * the first cycle after the @a timebase_callback is defined. * @param arg the argument supplied by jack_set_timebase_callback(). */ typedef void (*JackTimebaseCallback)(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *arg); /********************************************************************* * The following interfaces are DEPRECATED. They are only provided * for compatibility with the earlier JACK transport implementation. *********************************************************************/ /** * Optional struct jack_transport_info_t fields. * * @see jack_position_bits_t. */ typedef enum { JackTransportState = 0x1, /**< Transport state */ JackTransportPosition = 0x2, /**< Frame number */ JackTransportLoop = 0x4, /**< Loop boundaries (ignored) */ JackTransportSMPTE = 0x8, /**< SMPTE (ignored) */ JackTransportBBT = 0x10 /**< Bar, Beat, Tick */ } jack_transport_bits_t; /** * Deprecated struct for transport position information. * * @deprecated This is for compatibility with the earlier transport * interface. Use the jack_position_t struct, instead. */ typedef struct { /* these two cannot be set from clients: the server sets them */ jack_nframes_t frame_rate; /**< current frame rate (per second) */ jack_time_t usecs; /**< monotonic, free-rolling */ jack_transport_bits_t valid; /**< which fields are legal to read */ jack_transport_state_t transport_state; jack_nframes_t frame; jack_nframes_t loop_start; jack_nframes_t loop_end; long smpte_offset; /**< SMPTE offset (from frame 0) */ float smpte_frame_rate; /**< 29.97, 30, 24 etc. */ int bar; int beat; int tick; double bar_start_tick; float beats_per_bar; float beat_type; double ticks_per_beat; double beats_per_minute; } jack_transport_info_t; #endif /* __jack_types_h__ */ 1.9.12~dfsg/common/jack/metadata.h0000644000000000000000000001622213214314510015474 0ustar rootroot/* Copyright (C) 2011 David Robillard Copyright (C) 2013 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file jack/metadata.h * @ingroup publicheader * @brief JACK Metadata API * */ #ifndef __jack_metadata_h__ #define __jack_metadata_h__ #include #ifdef __cplusplus extern "C" { #endif /** * @defgroup Metadata Metadata API. * @{ */ /** * A single property (key:value pair). */ typedef struct { /** The key of this property (URI string). */ const char* key; /** The property value (null-terminated string). */ const char* data; /** * Type of data, either a MIME type or URI. * * If type is NULL or empty, the data is assumed to be a UTF-8 encoded * string (text/plain). The data is a null-terminated string regardless of * type, so values can always be copied, but clients should not try to * interpret values of an unknown type. * * Example values: * - image/png;base64 (base64 encoded PNG image) * - http://www.w3.org/2001/XMLSchema#int (integer) * * Official types are preferred, but clients may use any syntactically * valid MIME type (which start with a type and slash, like "text/..."). * If a URI type is used, it must be a complete absolute URI * (which start with a scheme and colon, like "http:"). */ const char* type; } jack_property_t; /** * Set a property on @p subject. * * See the above documentation for rules about @p subject and @p key. * @param subject The subject to set the property on. * @param key The key of the property. * @param value The value of the property. * @param type The type of the property. See the discussion of * types in the definition of jack_property_t above. * @return 0 on success. */ int jack_set_property(jack_client_t*, jack_uuid_t subject, const char* key, const char* value, const char* type); /** * Get a property on @p subject. * * @param subject The subject to get the property from. * @param key The key of the property. * @param value Set to the value of the property if found, or NULL otherwise. * The caller must free this value with jack_free(). * @param type The type of the property if set, or NULL. See the discussion * of types in the definition of jack_property_t above. * If non-null, the caller must free this value with jack_free(). * * @return 0 on success, -1 if the @p subject has no @p key property. */ int jack_get_property(jack_uuid_t subject, const char* key, char** value, char** type); /** * A description of a subject (a set of properties). */ typedef struct { jack_uuid_t subject; /**< Subject being described. */ uint32_t property_cnt; /**< Number of elements in "properties". */ jack_property_t* properties; /**< Array of properties. */ uint32_t property_size; /**< Private, do not use. */ } jack_description_t; /** * Free a description. * * @param desc a jack_description_t whose associated memory will all be released * @param free_description_itself if non-zero, then @param desc will also be passed to free() */ void jack_free_description (jack_description_t* desc, int free_description_itself); /** * Get a description of @p subject. * @param subject The subject to get all properties of. * @param desc Set to the description of subject if found, or NULL otherwise. * The caller must free this value with jack_free_description(). * @return 0 on success, -1 if no @p subject with any properties exists. */ int jack_get_properties (jack_uuid_t subject, jack_description_t* desc); /** * Get descriptions for all subjects with metadata. * @param descs Set to a NULL-terminated array of descriptions. * The caller must free each of these with jack_free_description(), * and the array itself with jack_free(). * @return 0 on success. */ int jack_get_all_properties (jack_description_t** descs); /** * Remove a single property on a subject. * * @param client The JACK client making the request to remove the property. * @param subject The subject to remove the property from. * @param key The key of the property to be removed. * * @return 0 on success, -1 otherwise */ int jack_remove_property (jack_client_t* client, jack_uuid_t subject, const char* key); /** * Remove all properties on a subject. * * @param client The JACK client making the request to remove some properties. * @param subject The subject to remove all properties from. * * @return a count of the number of properties removed, or -1 on error. */ int jack_remove_properties (jack_client_t* client, jack_uuid_t subject); /** * Remove all properties. * * WARNING!! This deletes all metadata managed by a running JACK server. * Data lost cannot be recovered (though it can be recreated by new calls * to jack_set_property()). * * @param client The JACK client making the request to remove all properties * * @return 0 on success, -1 otherwise */ int jack_remove_all_properties (jack_client_t* client); typedef enum { PropertyCreated, PropertyChanged, PropertyDeleted } jack_property_change_t; typedef void (*JackPropertyChangeCallback)(jack_uuid_t subject, const char* key, jack_property_change_t change, void* arg); /** * Arrange for @p client to call @p callback whenever a property is created, * changed or deleted. * * @param client the JACK client making the request * @param callback the function to be invoked when a property change occurs * @param arg the argument to be passed to @param callback when it is invoked * * @return 0 success, -1 otherwise. */ int jack_set_property_change_callback (jack_client_t* client, JackPropertyChangeCallback callback, void* arg); #ifdef __cplusplus } /* namespace */ #endif /** * @} */ extern const char* JACK_METADATA_PRETTY_NAME; extern const char* JACK_METADATA_HARDWARE; extern const char* JACK_METADATA_CONNECTED; extern const char* JACK_METADATA_PORT_GROUP; extern const char* JACK_METADATA_ICON_SMALL; extern const char* JACK_METADATA_ICON_LARGE; #endif /* __jack_metadata_h__ */ 1.9.12~dfsg/common/jack/midiport.h0000644000000000000000000001406513214314510015546 0ustar rootroot/* Copyright (C) 2004 Ian Esten This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JACK_MIDIPORT_H #define __JACK_MIDIPORT_H #ifdef __cplusplus extern "C" { #endif #include #include #include /** Type for raw event data contained in @ref jack_midi_event_t. */ typedef unsigned char jack_midi_data_t; /** A Jack MIDI event. */ typedef struct _jack_midi_event { jack_nframes_t time; /**< Sample index at which event is valid */ size_t size; /**< Number of bytes of data in \a buffer */ jack_midi_data_t *buffer; /**< Raw MIDI data */ } jack_midi_event_t; /** * @defgroup MIDIAPI Reading and writing MIDI data * @{ */ /** Get number of events in a port buffer. * * @param port_buffer Port buffer from which to retrieve event. * @return number of events inside @a port_buffer */ uint32_t jack_midi_get_event_count(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Get a MIDI event from an event port buffer. * * Jack MIDI is normalised, the MIDI event returned by this function is * guaranteed to be a complete MIDI event (the status byte will always be * present, and no realtime events will interspered with the event). * * @param event Event structure to store retrieved event in. * @param port_buffer Port buffer from which to retrieve event. * @param event_index Index of event to retrieve. * @return 0 on success, ENODATA if buffer is empty. */ int jack_midi_event_get(jack_midi_event_t *event, void *port_buffer, uint32_t event_index) JACK_OPTIONAL_WEAK_EXPORT; /** Clear an event buffer. * * This should be called at the beginning of each process cycle before calling * @ref jack_midi_event_reserve or @ref jack_midi_event_write. This * function may not be called on an input port's buffer. * * @param port_buffer Port buffer to clear (must be an output port buffer). */ void jack_midi_clear_buffer(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Reset an event buffer (from data allocated outside of JACK). * * This should be called at the beginning of each process cycle before calling * @ref jack_midi_event_reserve or @ref jack_midi_event_write. This * function may not be called on an input port's buffer. * * @param port_buffer Port buffer to resetted. */ void jack_midi_reset_buffer(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Get the size of the largest event that can be stored by the port. * * This function returns the current space available, taking into account * events already stored in the port. * * @param port_buffer Port buffer to check size of. */ size_t jack_midi_max_event_size(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Allocate space for an event to be written to an event port buffer. * * Clients are to write the actual event data to be written starting at the * pointer returned by this function. Clients must not write more than * @a data_size bytes into this buffer. Clients must write normalised * MIDI data to the port - no running status and no (1-byte) realtime * messages interspersed with other messages (realtime messages are fine * when they occur on their own, like other messages). * * Events must be written in order, sorted by their sample offsets. * JACK will not sort the events for you, and will refuse to store * out-of-order events. * * @param port_buffer Buffer to write event to. * @param time Sample offset of event. * @param data_size Length of event's raw data in bytes. * @return Pointer to the beginning of the reserved event's data buffer, or * NULL on error (ie not enough space). */ jack_midi_data_t* jack_midi_event_reserve(void *port_buffer, jack_nframes_t time, size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; /** Write an event into an event port buffer. * * This function is simply a wrapper for @ref jack_midi_event_reserve * which writes the event data into the space reserved in the buffer. * * Clients must not write more than * @a data_size bytes into this buffer. Clients must write normalised * MIDI data to the port - no running status and no (1-byte) realtime * messages interspersed with other messages (realtime messages are fine * when they occur on their own, like other messages). * * Events must be written in order, sorted by their sample offsets. * JACK will not sort the events for you, and will refuse to store * out-of-order events. * * @param port_buffer Buffer to write event to. * @param time Sample offset of event. * @param data Message data to be written. * @param data_size Length of @a data in bytes. * @return 0 on success, ENOBUFS if there's not enough space in buffer for event. */ int jack_midi_event_write(void *port_buffer, jack_nframes_t time, const jack_midi_data_t *data, size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; /** Get the number of events that could not be written to @a port_buffer. * * This function returning a non-zero value implies @a port_buffer is full. * Currently the only way this can happen is if events are lost on port mixdown. * * @param port_buffer Port to receive count for. * @returns Number of events that could not be written to @a port_buffer. */ uint32_t jack_midi_get_lost_event_count(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ #ifdef __cplusplus } #endif #endif /* __JACK_MIDIPORT_H */ 1.9.12~dfsg/common/jack/systemdeps.h0000644000000000000000000001117013214314510016111 0ustar rootroot/* Copyright (C) 2004-2012 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __jack_systemdeps_h__ #define __jack_systemdeps_h__ #ifndef POST_PACKED_STRUCTURE #ifdef __GNUC__ /* POST_PACKED_STRUCTURE needs to be a macro which expands into a compiler directive. The directive must tell the compiler to arrange the preceding structure declaration so that it is packed on byte-boundaries rather than use the natural alignment of the processor and/or compiler. */ #define PRE_PACKED_STRUCTURE #define POST_PACKED_STRUCTURE __attribute__((__packed__)) #else #ifdef _MSC_VER #define PRE_PACKED_STRUCTURE1 __pragma(pack(push,1)) #define PRE_PACKED_STRUCTURE PRE_PACKED_STRUCTURE1 /* PRE_PACKED_STRUCTURE needs to be a macro which expands into a compiler directive. The directive must tell the compiler to arrange the following structure declaration so that it is packed on byte-boundaries rather than use the natural alignment of the processor and/or compiler. */ #define POST_PACKED_STRUCTURE ;__pragma(pack(pop)) /* and POST_PACKED_STRUCTURE needs to be a macro which restores the packing to its previous setting */ #else #define PRE_PACKED_STRUCTURE #define POST_PACKED_STRUCTURE #endif /* _MSC_VER */ #endif /* __GNUC__ */ #endif #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(GNU_WIN32) #ifdef __MINGW32__ # include // mingw gives warning if we include windows.h before winsock2.h #endif #include #ifdef _MSC_VER /* Microsoft compiler */ #define __inline__ inline #if (!defined(int8_t) && !defined(_STDINT_H)) #define __int8_t_defined typedef char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; typedef long int32_t; typedef unsigned long uint32_t; typedef LONGLONG int64_t; typedef ULONGLONG uint64_t; #endif #elif __MINGW32__ /* MINGW */ #include #include #else /* other compilers ...*/ #include #include #include #endif #if !defined(_PTHREAD_H) && !defined(PTHREAD_WIN32) /** * to make jack API independent of different thread implementations, * we define jack_native_thread_t to HANDLE here. */ typedef HANDLE jack_native_thread_t; #else #ifdef PTHREAD_WIN32 // Added by JE - 10-10-2011 #include // Makes sure we #include the ptw32 version ! #endif /** * to make jack API independent of different thread implementations, * we define jack_native_thread_t to pthread_t here. */ typedef pthread_t jack_native_thread_t; #endif #endif /* _WIN32 && !__CYGWIN__ && !GNU_WIN32 */ #if defined(__APPLE__) || defined(__linux__) || defined(__sun__) || defined(sun) || defined(__unix__) || defined(__CYGWIN__) || defined(GNU_WIN32) #if defined(__CYGWIN__) || defined(GNU_WIN32) #include #endif #include #include #include /** * to make jack API independent of different thread implementations, * we define jack_native_thread_t to pthread_t here. */ typedef pthread_t jack_native_thread_t; #endif /* __APPLE__ || __linux__ || __sun__ || sun */ #if defined(__arm__) || defined(__aarch64__) || defined(__mips__) || defined(__ppc__) || defined(__powerpc__) #undef POST_PACKED_STRUCTURE #define POST_PACKED_STRUCTURE #endif /* __arm__ || __aarch64__ || __ppc__ || __powerpc__ */ #endif /* __jack_systemdeps_h__ */ 1.9.12~dfsg/common/jack/net.h0000644000000000000000000003573713214314510014516 0ustar rootroot/* Copyright (C) 2009-2010 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __net_h__ #define __net_h__ #ifdef __cplusplus extern "C" { #endif #include #include #include #define DEFAULT_MULTICAST_IP "225.3.19.154" #define DEFAULT_PORT 19000 #define DEFAULT_MTU 1500 #define MASTER_NAME_SIZE 256 // Possible error codes #define NO_ERROR 0 #define SOCKET_ERROR -1 #define SYNC_PACKET_ERROR -2 #define DATA_PACKET_ERROR -3 #define RESTART_CB_API 1 enum JackNetEncoder { JackFloatEncoder = 0, // samples are transmitted as float JackIntEncoder = 1, // samples are transmitted as 16 bits integer JackCeltEncoder = 2, // samples are transmitted using CELT codec (http://www.celt-codec.org/) JackOpusEncoder = 3, // samples are transmitted using OPUS codec (http://www.opus-codec.org/) }; typedef struct { int audio_input; // from master or to slave (-1 to take master audio physical inputs) int audio_output; // to master or from slave (-1 to take master audio physical outputs) int midi_input; // from master or to slave (-1 to take master MIDI physical inputs) int midi_output; // to master or from slave (-1 to take master MIDI physical outputs) int mtu; // network Maximum Transmission Unit int time_out; // in second, -1 means infinite int encoder; // encoder type (one of JackNetEncoder) int kbps; // KB per second for CELT or OPUS codec int latency; // network latency in number of buffers } jack_slave_t; typedef struct { int audio_input; // master audio physical outputs (-1 to take slave wanted audio inputs) int audio_output; // master audio physical inputs (-1 to take slave wanted audio outputs) int midi_input; // master MIDI physical outputs (-1 to take slave wanted MIDI inputs) int midi_output; // master MIDI physical inputs (-1 to take slave wanted MIDI outputs) jack_nframes_t buffer_size; // master buffer size jack_nframes_t sample_rate; // master sample rate char master_name[MASTER_NAME_SIZE]; // master machine name int time_out; // in second, -1 means infinite int partial_cycle; // if 'true', partial buffers will be used } jack_master_t; /** * jack_net_slave_t is an opaque type. You may only access it using the * API provided. */ typedef struct _jack_net_slave jack_net_slave_t; /** * Open a network connection with the master machine. * * @param ip the multicast address of the master * @param port the connection port * @param name the JACK client name * @param request a connection request structure * @param result a connection result structure * * @return Opaque net handle if successful or NULL in case of error. */ jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result); /** * Close the network connection with the master machine. * * @param net the network connection to be closed * * @return 0 on success, otherwise a non-zero error code */ int jack_net_slave_close(jack_net_slave_t* net); /** * Prototype for Process callback. * * @param nframes buffer size * @param audio_input number of audio inputs * @param audio_input_buffer an array of audio input buffers (from master) * @param midi_input number of MIDI inputs * @param midi_input_buffer an array of MIDI input buffers (from master) * @param audio_output number of audio outputs * @param audio_output_buffer an array of audio output buffers (to master) * @param midi_output number of MIDI outputs * @param midi_output_buffer an array of MIDI output buffers (to master) * @param arg pointer to a client supplied structure supplied by jack_set_net_process_callback() * * @return zero on success, non-zero on error */ typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, void* data); /** * Set network process callback. * * @param net the network connection * @param net_callback the process callback * @param arg pointer to a client supplied structure * * @return 0 on success, otherwise a non-zero error code */ int jack_set_net_slave_process_callback(jack_net_slave_t * net, JackNetSlaveProcessCallback net_callback, void *arg); /** * Start processing thread, the net_callback will start to be called. * * @param net the network connection * * @return 0 on success, otherwise a non-zero error code */ int jack_net_slave_activate(jack_net_slave_t* net); /** * Stop processing thread. * * @param net the network connection * * @return 0 on success, otherwise a non-zero error code */ int jack_net_slave_deactivate(jack_net_slave_t* net); /** * Test if slave is still active. * * @param net the network connection * * @return a boolean */ int jack_net_slave_is_active(jack_net_slave_t* net); /** * Prototype for BufferSize callback. * * @param nframes buffer size * @param arg pointer to a client supplied structure supplied by jack_set_net_buffer_size_callback() * * @return zero on success, non-zero on error */ typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg); /** * Set network buffer size callback. * * @param net the network connection * @param bufsize_callback the buffer size callback * @param arg pointer to a client supplied structure * * @return 0 on success, otherwise a non-zero error code */ int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg); /** * Prototype for SampleRate callback. * * @param nframes sample rate * @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback() * * @return zero on success, non-zero on error */ typedef int (*JackNetSlaveSampleRateCallback)(jack_nframes_t nframes, void *arg); /** * Set network sample rate callback. * * @param net the network connection * @param samplerate_callback the sample rate callback * @param arg pointer to a client supplied structure * * @return 0 on success, otherwise a non-zero error code */ int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); /** * Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again). * * @param arg pointer to a client supplied structure supplied by jack_set_net_shutdown_callback() */ typedef void (*JackNetSlaveShutdownCallback)(void* arg); /** * Set network shutdown callback. * * @param net the network connection * @param shutdown_callback the shutdown callback * @param arg pointer to a client supplied structure * * @return 0 on success, otherwise a non-zero error code */ int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Prototype for server Restart callback : this is the new preferable way to be notified when the master has disappeared. * The client may want to retry connecting a certain number of time (which will be done using the time_out value given in jack_net_slave_open) * by returning 0. Otherwise returning a non-zero error code will definively close the connection * (and jack_net_slave_is_active will later on return false). * If both Shutdown and Restart are supplied, Restart callback will be used. * * @param arg pointer to a client supplied structure supplied by jack_set_net_restart_callback() * * @return 0 on success, otherwise a non-zero error code */ typedef int (*JackNetSlaveRestartCallback)(void* arg); /** * Set network restart callback. * * @param net the network connection * @param restart_callback the shutdown callback * @param arg pointer to a client supplied structure * * @return 0 on success, otherwise a non-zero error code */ int jack_set_net_slave_restart_callback(jack_net_slave_t *net, JackNetSlaveRestartCallback restart_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Prototype for server Error callback. * * @param error_code an error code (see "Possible error codes") * @param arg pointer to a client supplied structure supplied by jack_set_net_error_callback() */ typedef void (*JackNetSlaveErrorCallback) (int error_code, void* arg); /** * Set error restart callback. * * @param net the network connection * @param error_callback the error callback * @param arg pointer to a client supplied structure * * @return 0 on success, otherwise a non-zero error code */ int jack_set_net_slave_error_callback(jack_net_slave_t *net, JackNetSlaveErrorCallback error_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * jack_net_master_t is an opaque type, you may only access it using the API provided. */ typedef struct _jack_net_master jack_net_master_t; /** * Open a network connection with the slave machine. * * @param ip the multicast address of the master * @param port the connection port * @param request a connection request structure * @param result a connection result structure * * @return Opaque net handle if successful or NULL in case of error. */ jack_net_master_t* jack_net_master_open(const char* ip, int port, jack_master_t* request, jack_slave_t* result); /** * Close the network connection with the slave machine. * * @param net the network connection to be closed * * @return 0 on success, otherwise a non-zero error code */ int jack_net_master_close(jack_net_master_t* net); /** * Receive sync and data from the network (complete buffer). * * @param net the network connection * @param audio_input number of audio inputs * @param audio_input_buffer an array of audio input buffers * @param midi_input number of MIDI inputs * @param midi_input_buffer an array of MIDI input buffers * * @return zero on success, non-zero on error */ int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); /** * Receive sync and data from the network (incomplete buffer). * * @param net the network connection * @param audio_input number of audio inputs * @param audio_input_buffer an array of audio input buffers * @param midi_input number of MIDI inputs * @param midi_input_buffer an array of MIDI input buffers * @param frames the number of frames to receive * * @return zero on success, non-zero on error */ int jack_net_master_recv_slice(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames); /** * Send sync and data to the network (complete buffer). * * @param net the network connection * @param audio_output number of audio outputs * @param audio_output_buffer an array of audio output buffers * @param midi_output number of MIDI ouputs * @param midi_output_buffer an array of MIDI output buffers * * @return zero on success, non-zero on error */ int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); /** * Send sync and data to the network (incomplete buffer). * * @param net the network connection * @param audio_output number of audio outputs * @param audio_output_buffer an array of audio output buffers * @param midi_output number of MIDI ouputs * @param midi_output_buffer an array of MIDI output buffers * @param frames the number of frames to send * * @return zero on success, non-zero on error */ int jack_net_master_send_slice(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames); // Experimental Adapter API /** * jack_adapter_t is an opaque type, you may only access it using the API provided. */ typedef struct _jack_adapter jack_adapter_t; /** * Create an adapter. * * @param input number of audio inputs * @param output of audio outputs * @param host_buffer_size the host buffer size in frames * @param host_sample_rate the host buffer sample rate * @param adapted_buffer_size the adapted buffer size in frames * @param adapted_sample_rate the adapted buffer sample rate * * @return 0 on success, otherwise a non-zero error code */ jack_adapter_t* jack_create_adapter(int input, int output, jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate); /** * Destroy an adapter. * * @param adapter the adapter to be destroyed * * @return 0 on success, otherwise a non-zero error code */ int jack_destroy_adapter(jack_adapter_t* adapter); /** * Flush internal state of an adapter. * * @param adapter the adapter to be flushed * * @return 0 on success, otherwise a non-zero error code */ void jack_flush_adapter(jack_adapter_t* adapter); /** * Push input to and pull output from adapter ringbuffer. * * @param adapter the adapter * @param input an array of audio input buffers * @param output an array of audio ouput buffers * @param frames number of frames * * @return 0 on success, otherwise a non-zero error code */ int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); /** * Pull input from and push output to adapter ringbuffer. * * @param adapter the adapter * @param input an array of audio input buffers * @param output an array of audio ouput buffers * @param frames number of frames * * @return 0 on success, otherwise a non-zero error code */ int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); #ifdef __cplusplus } #endif #endif /* __net_h__ */ 1.9.12~dfsg/common/jack/control.h0000644000000000000000000004116313214314510015376 0ustar rootroot/* -*- Mode: C ; c-basic-offset: 4 -*- */ /* JACK control API Copyright (C) 2008 Nedko Arnaudov Copyright (C) 2008 GRAME This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /** * @file jack/control.h * @ingroup publicheader * @brief JACK control API * */ #ifndef JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED #define JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED #include #include #include #if !defined(sun) && !defined(__sun__) #include #endif /** Parameter types, intentionally similar to jack_driver_param_type_t */ typedef enum { JackParamInt = 1, /**< @brief value type is a signed integer */ JackParamUInt, /**< @brief value type is an unsigned integer */ JackParamChar, /**< @brief value type is a char */ JackParamString, /**< @brief value type is a string with max size of ::JACK_PARAM_STRING_MAX+1 chars */ JackParamBool, /**< @brief value type is a boolean */ } jackctl_param_type_t; /** Driver types */ typedef enum { JackMaster = 1, /**< @brief master driver */ JackSlave /**< @brief slave driver */ } jackctl_driver_type_t; /** @brief Max value that jackctl_param_type_t type can have */ #define JACK_PARAM_MAX (JackParamBool + 1) /** @brief Max length of string parameter value, excluding terminating null char */ #define JACK_PARAM_STRING_MAX 127 /** @brief Type for parameter value */ /* intentionally similar to jack_driver_param_value_t */ union jackctl_parameter_value { uint32_t ui; /**< @brief member used for ::JackParamUInt */ int32_t i; /**< @brief member used for ::JackParamInt */ char c; /**< @brief member used for ::JackParamChar */ char str[JACK_PARAM_STRING_MAX + 1]; /**< @brief member used for ::JackParamString */ bool b; /**< @brief member used for ::JackParamBool */ }; /** opaque type for server object */ typedef struct jackctl_server jackctl_server_t; /** opaque type for driver object */ typedef struct jackctl_driver jackctl_driver_t; /** opaque type for internal client object */ typedef struct jackctl_internal jackctl_internal_t; /** opaque type for parameter object */ typedef struct jackctl_parameter jackctl_parameter_t; /** opaque type for sigmask object */ typedef struct jackctl_sigmask jackctl_sigmask_t; #ifdef __cplusplus extern "C" { #endif #if 0 } /* Adjust editor indent */ #endif /** * @defgroup ControlAPI The API for starting and controlling a JACK server * @{ */ /** * Call this function to setup process signal handling. As a general * rule, it is required for proper operation for the server object. * * @param flags signals setup flags, use 0 for none. Currently no * flags are defined * * @return the configurated signal set. */ jackctl_sigmask_t * jackctl_setup_signals( unsigned int flags); /** * Call this function to wait on a signal set. * * @param signals signals set to wait on */ void jackctl_wait_signals( jackctl_sigmask_t * signals); /** * Call this function to create server object. * * @param on_device_acquire - Optional callback to be called before device is acquired. If false is returned, device usage will fail * @param on_device_release - Optional callback to be called after device is released. * * @return server object handle, NULL if creation of server object * failed. Successfully created server object must be destroyed with * paired call to ::jackctl_server_destroy */ jackctl_server_t * jackctl_server_create( bool (* on_device_acquire)(const char * device_name), void (* on_device_release)(const char * device_name)); /** * Call this function to destroy server object. * * @param server server object handle to destroy */ void jackctl_server_destroy( jackctl_server_t * server); /** * Call this function to open JACK server * * @param server server object handle * @param driver driver to use * * @return success status: true - success, false - fail */ bool jackctl_server_open( jackctl_server_t * server, jackctl_driver_t * driver); /** * Call this function to start JACK server * * @param server server object handle * * @return success status: true - success, false - fail */ bool jackctl_server_start( jackctl_server_t * server); /** * Call this function to stop JACK server * * @param server server object handle * * @return success status: true - success, false - fail */ bool jackctl_server_stop( jackctl_server_t * server); /** * Call this function to close JACK server * * @param server server object handle * * @return success status: true - success, false - fail */ bool jackctl_server_close( jackctl_server_t * server); /** * Call this function to get list of available drivers. List node data * pointers is a driver object handle (::jackctl_driver_t). * * @param server server object handle to get drivers for * * @return Single linked list of driver object handles. Must not be * modified. Always same for same server object. */ const JSList * jackctl_server_get_drivers_list( jackctl_server_t * server); /** * Call this function to get list of server parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). * * @param server server object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be * modified. Always same for same server object. */ const JSList * jackctl_server_get_parameters( jackctl_server_t * server); /** * Call this function to get list of available internal clients. List node data * pointers is a internal client object handle (::jackctl_internal_t). * * @param server server object handle to get internal clients for * * @return Single linked list of internal client object handles. Must not be * modified. Always same for same server object. */ const JSList * jackctl_server_get_internals_list( jackctl_server_t * server); /** * Call this function to load one internal client. * (can be used when the server is running) * * @param server server object handle * @param internal internal to use * * @return success status: true - success, false - fail */ bool jackctl_server_load_internal( jackctl_server_t * server, jackctl_internal_t * internal); /** * Call this function to unload one internal client. * (can be used when the server is running) * * @param server server object handle * @param internal internal to unload * * @return success status: true - success, false - fail */ bool jackctl_server_unload_internal( jackctl_server_t * server, jackctl_internal_t * internal); /** * Call this function to load a session file. * (can be used when the server is running) * * @param server server object handle * @param file the session file to load, containing a list of * internal clients and connections to be made. * * @return success status: true - success, false - fail */ bool jackctl_server_load_session_file( jackctl_server_t * server_ptr, const char * file); /** * Call this function to add a slave in the driver slave list. * (cannot be used when the server is running that is between * jackctl_server_start and jackctl_server_stop) * * @param server server object handle * @param driver driver to add in the driver slave list. * * @return success status: true - success, false - fail */ bool jackctl_server_add_slave(jackctl_server_t * server, jackctl_driver_t * driver); /** * Call this function to remove a slave from the driver slave list. * (cannot be used when the server is running that is between * jackctl_server_start and jackctl_server_stop) * * @param server server object handle * @param driver driver to remove from the driver slave list. * * @return success status: true - success, false - fail */ bool jackctl_server_remove_slave(jackctl_server_t * server, jackctl_driver_t * driver); /** * Call this function to switch master driver. * * @param server server object handle * @param driver driver to switch to * * @return success status: true - success, false - fail */ bool jackctl_server_switch_master(jackctl_server_t * server, jackctl_driver_t * driver); /** * Call this function to get name of driver. * * @param driver driver object handle to get name of * * @return driver name. Must not be modified. Always same for same * driver object. */ const char * jackctl_driver_get_name( jackctl_driver_t * driver); /** * Call this function to get type of driver. * * @param driver driver object handle to get name of * * @return driver type. Must not be modified. Always same for same * driver object. */ jackctl_driver_type_t jackctl_driver_get_type( jackctl_driver_t * driver); /** * Call this function to get list of driver parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). * * @param driver driver object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be * modified. Always same for same driver object. */ const JSList * jackctl_driver_get_parameters( jackctl_driver_t * driver); /** * Call this function to parse parameters for a driver. * * @param driver driver object handle * @param argc parameter list len * @param argv parameter list, as an array of char* * * @return success status: true - success, false - fail */ int jackctl_driver_params_parse( jackctl_driver_t * driver, int argc, char* argv[]); /** * Call this function to get name of internal client. * * @param internal internal object handle to get name of * * @return internal name. Must not be modified. Always same for same * internal object. */ const char * jackctl_internal_get_name( jackctl_internal_t * internal); /** * Call this function to get list of internal parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). * * @param internal internal object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be * modified. Always same for same internal object. */ const JSList * jackctl_internal_get_parameters( jackctl_internal_t * internal); /** * Call this function to get parameter name. * * @param parameter parameter object handle to get name of * * @return parameter name. Must not be modified. Always same for same * parameter object. */ const char * jackctl_parameter_get_name( jackctl_parameter_t * parameter); /** * Call this function to get parameter short description. * * @param parameter parameter object handle to get short description of * * @return parameter short description. Must not be modified. Always * same for same parameter object. */ const char * jackctl_parameter_get_short_description( jackctl_parameter_t * parameter); /** * Call this function to get parameter long description. * * @param parameter parameter object handle to get long description of * * @return parameter long description. Must not be modified. Always * same for same parameter object. */ const char * jackctl_parameter_get_long_description( jackctl_parameter_t * parameter); /** * Call this function to get parameter type. * * @param parameter parameter object handle to get type of * * @return parameter type. Always same for same parameter object. */ jackctl_param_type_t jackctl_parameter_get_type( jackctl_parameter_t * parameter); /** * Call this function to get parameter character. * * @param parameter parameter object handle to get character of * * @return character. */ char jackctl_parameter_get_id( jackctl_parameter_t * parameter); /** * Call this function to check whether parameter has been set, or its * default value is being used. * * @param parameter parameter object handle to check * * @return true - parameter is set, false - parameter is using default * value. */ bool jackctl_parameter_is_set( jackctl_parameter_t * parameter); /** * Call this function to reset parameter to its default value. * * @param parameter parameter object handle to reset value of * * @return success status: true - success, false - fail */ bool jackctl_parameter_reset( jackctl_parameter_t * parameter); /** * Call this function to get parameter value. * * @param parameter parameter object handle to get value of * * @return parameter value. */ union jackctl_parameter_value jackctl_parameter_get_value( jackctl_parameter_t * parameter); /** * Call this function to set parameter value. * * @param parameter parameter object handle to get value of * @param value_ptr pointer to variable containing parameter value * * @return success status: true - success, false - fail */ bool jackctl_parameter_set_value( jackctl_parameter_t * parameter, const union jackctl_parameter_value * value_ptr); /** * Call this function to get parameter default value. * * @param parameter parameter object handle to get default value of * * @return parameter default value. */ union jackctl_parameter_value jackctl_parameter_get_default_value( jackctl_parameter_t * parameter); /** * Call this function check whether parameter has range constraint. * * @param parameter object handle of parameter to check * * @return whether parameter has range constraint. */ bool jackctl_parameter_has_range_constraint( jackctl_parameter_t * parameter); /** * Call this function check whether parameter has enumeration constraint. * * @param parameter object handle of parameter to check * * @return whether parameter has enumeration constraint. */ bool jackctl_parameter_has_enum_constraint( jackctl_parameter_t * parameter); /** * Call this function get how many enumeration values parameter has. * * @param parameter object handle of parameter * * @return number of enumeration values */ uint32_t jackctl_parameter_get_enum_constraints_count( jackctl_parameter_t * parameter); /** * Call this function to get parameter enumeration value. * * @param parameter object handle of parameter * @param index index of parameter enumeration value * * @return enumeration value. */ union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value( jackctl_parameter_t * parameter, uint32_t index); /** * Call this function to get parameter enumeration value description. * * @param parameter object handle of parameter * @param index index of parameter enumeration value * * @return enumeration value description. */ const char * jackctl_parameter_get_enum_constraint_description( jackctl_parameter_t * parameter, uint32_t index); /** * Call this function to get parameter range. * * @param parameter object handle of parameter * @param min_ptr pointer to variable receiving parameter minimum value * @param max_ptr pointer to variable receiving parameter maximum value */ void jackctl_parameter_get_range_constraint( jackctl_parameter_t * parameter, union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr); /** * Call this function to check whether parameter constraint is strict, * i.e. whether supplying non-matching value will not work for sure. * * @param parameter parameter object handle to check * * @return whether parameter constraint is strict. */ bool jackctl_parameter_constraint_is_strict( jackctl_parameter_t * parameter); /** * Call this function to check whether parameter has fake values, * i.e. values have no user meaningful meaning and only value * description is meaningful to user. * * @param parameter parameter object handle to check * * @return whether parameter constraint is strict. */ bool jackctl_parameter_constraint_is_fake_value( jackctl_parameter_t * parameter); /** * Call this function to log an error message. * * @param format string */ void jack_error( const char *format, ...); /** * Call this function to log an information message. * * @param format string */ void jack_info( const char *format, ...); /** * Call this function to log an information message but only when * verbose mode is enabled. * * @param format string */ void jack_log( const char *format, ...); /* @} */ #if 0 { /* Adjust editor indent */ #endif #ifdef __cplusplus } /* extern "C" */ #endif #endif /* #ifndef JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED */ 1.9.12~dfsg/common/jack/statistics.h0000644000000000000000000000345413214314510016111 0ustar rootroot/* * Copyright (C) 2004 Rui Nuno Capela, Lee Revell * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * */ #ifndef __statistics_h__ #define __statistics_h__ #ifdef __cplusplus extern "C" { #endif #include /** * @return the maximum delay reported by the backend since * startup or reset. When compared to the period size in usecs, this * can be used to estimate the ideal period size for a given setup. */ float jack_get_max_delayed_usecs (jack_client_t *client); /** * @return the delay in microseconds due to the most recent XRUN * occurrence. This probably only makes sense when called from a @ref * JackXRunCallback defined using jack_set_xrun_callback(). */ float jack_get_xrun_delayed_usecs (jack_client_t *client); /** * Reset the maximum delay counter. This would be useful * to estimate the effect that a change to the configuration of a running * system (e.g. toggling kernel preemption) has on the delay * experienced by JACK, without having to restart the JACK engine. */ void jack_reset_max_delayed_usecs (jack_client_t *client); #ifdef __cplusplus } #endif #endif /* __statistics_h__ */ 1.9.12~dfsg/common/jack/thread.h0000644000000000000000000001212613214314510015162 0ustar rootroot/* Copyright (C) 2004 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_thread_h__ #define __jack_thread_h__ #ifdef __cplusplus extern "C" { #endif #include #include /* use 512KB stack per thread - the default is way too high to be feasible * with mlockall() on many systems */ #define THREAD_STACK 524288 /** @file thread.h * * Library functions to standardize thread creation for JACK and its * clients. These interfaces hide some system variations in the * handling of realtime scheduling and associated privileges. */ /** * @defgroup ClientThreads Creating and managing client threads * @{ */ /** * @returns if JACK is running with realtime scheduling, this returns * the priority that any JACK-created client threads will run at. * Otherwise returns -1. */ int jack_client_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; /** * @returns if JACK is running with realtime scheduling, this returns * the maximum priority that a JACK client thread should use if the thread * is subject to realtime scheduling. Otherwise returns -1. */ int jack_client_max_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; /** * Attempt to enable realtime scheduling for a thread. On some * systems that may require special privileges. * * @param thread POSIX thread ID. * @param priority requested thread priority. * * @returns 0, if successful; EPERM, if the calling process lacks * required realtime privileges; otherwise some other error number. */ int jack_acquire_real_time_scheduling (jack_native_thread_t thread, int priority) JACK_OPTIONAL_WEAK_EXPORT; /** * Create a thread for JACK or one of its clients. The thread is * created executing @a start_routine with @a arg as its sole * argument. * * @param client the JACK client for whom the thread is being created. May be * NULL if the client is being created within the JACK server. * @param thread place to return POSIX thread ID. * @param priority thread priority, if realtime. * @param realtime true for the thread to use realtime scheduling. On * some systems that may require special privileges. * @param start_routine function the thread calls when it starts. * @param arg parameter passed to the @a start_routine. * * @returns 0, if successful; otherwise some error number. */ int jack_client_create_thread (jack_client_t* client, jack_native_thread_t *thread, int priority, int realtime, /* boolean */ void *(*start_routine)(void*), void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Drop realtime scheduling for a thread. * * @param thread POSIX thread ID. * * @returns 0, if successful; otherwise an error number. */ int jack_drop_real_time_scheduling (jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** * Stop the thread, waiting for the thread handler to terminate. * * @param thread POSIX thread ID. * * @returns 0, if successful; otherwise an error number. */ int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** * Kill the thread. * * @param thread POSIX thread ID. * * @returns 0, if successful; otherwise an error number. */ int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; #ifndef _WIN32 typedef int (*jack_thread_creator_t)(pthread_t*, const pthread_attr_t*, void* (*function)(void*), void* arg); /** * This function can be used in very very specialized cases * where it is necessary that client threads created by JACK * are created by something other than pthread_create(). After * it is used, any threads that JACK needs for the client will * will be created by calling the function passed to this * function. * * No normal application/client should consider calling this. * The specific case for which it was created involves running * win32/x86 plugins under Wine on Linux, where it is necessary * that all threads that might call win32 functions are known * to Wine. * * Set it to NULL to restore thread creation function. * * @param creator a function that creates a new thread * */ void jack_set_thread_creator (jack_thread_creator_t creator) JACK_OPTIONAL_WEAK_EXPORT; #endif /* @} */ #ifdef __cplusplus } #endif #endif /* __jack_thread_h__ */ 1.9.12~dfsg/common/jack/session.h0000644000000000000000000002010713214314510015374 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Jack O'Quin Copyright (C) 2010 Torben Hohn This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_session_h__ #define __jack_session_h__ #ifdef __cplusplus extern "C" { #endif #include #include /** * @defgroup SessionClientFunctions Session API for clients. * @{ */ /** * Session event type. * * If a client cant save templates, i might just do a normal save. * * There is no "quit without saving" event because a client might refuse to * quit when it has unsaved data, but other clients may have already quit. * This results in too much confusion, so it is unsupported. */ enum JackSessionEventType { /** * Save the session completely. * * The client may save references to data outside the provided directory, * but it must do so by creating a link inside the provided directory and * referring to that in any save files. The client must not refer to data * files outside the provided directory directly in save files, because * this makes it impossible for the session manager to create a session * archive for distribution or archival. */ JackSessionSave = 1, /** * Save the session completly, then quit. * * The rules for saving are exactly the same as for JackSessionSave. */ JackSessionSaveAndQuit = 2, /** * Save a session template. * * A session template is a "skeleton" of the session, but without any data. * Clients must save a session that, when restored, will create the same * ports as a full save would have. However, the actual data contained in * the session may not be saved (e.g. a DAW would create the necessary * tracks, but not save the actual recorded data). */ JackSessionSaveTemplate = 3 }; typedef enum JackSessionEventType jack_session_event_type_t; /** * @ref jack_session_flags_t bits */ enum JackSessionFlags { /** * An error occured while saving. */ JackSessionSaveError = 0x01, /** * Client needs to be run in a terminal. */ JackSessionNeedTerminal = 0x02 }; /** * Session flags. */ typedef enum JackSessionFlags jack_session_flags_t; struct _jack_session_event { /** * The type of this session event. */ jack_session_event_type_t type; /** * Session directory path, with trailing separator. * * This directory is exclusive to the client; when saving the client may * create any files it likes in this directory. */ const char *session_dir; /** * Client UUID which must be passed to jack_client_open on session load. * * The client can specify this in the returned command line, or save it * in a state file within the session directory. */ const char *client_uuid; /** * Reply (set by client): the command line needed to restore the client. * * This is a platform dependent command line. It must contain * ${SESSION_DIR} instead of the actual session directory path. More * generally, just as in session files, clients should not include any * paths outside the session directory here as this makes * archival/distribution impossible. * * This field is set to NULL by Jack when the event is delivered to the * client. The client must set to allocated memory that is safe to * free(). This memory will be freed by jack_session_event_free. */ char *command_line; /** * Reply (set by client): Session flags. */ jack_session_flags_t flags; /** * Future flags. Set to zero for now. */ uint32_t future; }; typedef struct _jack_session_event jack_session_event_t; /** * Prototype for the client supplied function that is called * whenever a session notification is sent via jack_session_notify(). * * Ownership of the memory of @a event is passed to the application. * It must be freed using jack_session_event_free when its not used anymore. * * The client must promptly call jack_session_reply for this event. * * @param event The event structure. * @param arg Pointer to a client supplied structure. */ typedef void (*JackSessionCallback)(jack_session_event_t *event, void *arg); /** * Tell the JACK server to call @a session_callback when a session event * is to be delivered. * * setting more than one session_callback per process is probably a design * error. if you have a multiclient application its more sensible to create * a jack_client with only a session callback set. * * @return 0 on success, otherwise a non-zero error code */ int jack_set_session_callback (jack_client_t *client, JackSessionCallback session_callback, void *arg) JACK_WEAK_EXPORT; /** * Reply to a session event. * * This can either be called directly from the callback, or later from a * different thread. For example, it is possible to push the event through a * queue and execute the save code from the GUI thread. * * @return 0 on success, otherwise a non-zero error code */ int jack_session_reply (jack_client_t *client, jack_session_event_t *event) JACK_WEAK_EXPORT; /** * Free memory used by a jack_session_event_t. * * This also frees the memory used by the command_line pointer, if its non NULL. */ void jack_session_event_free (jack_session_event_t *event) JACK_WEAK_EXPORT; /** * Get the assigned uuid for client. * Safe to call from callback and all other threads. * * The caller is responsible for calling jack_free(3) on any non-NULL * returned value. */ char *jack_client_get_uuid (jack_client_t *client) JACK_WEAK_EXPORT; /** * @} */ /** * @defgroup JackSessionManagerAPI API for a session manager. * * @{ */ typedef struct { const char *uuid; const char *client_name; const char *command; jack_session_flags_t flags; } jack_session_command_t; /** * Send an event to all clients listening for session callbacks. * * The returned strings of the clients are accumulated and returned as an array * of jack_session_command_t. its terminated by ret[i].uuid == NULL target == * NULL means send to all interested clients. otherwise a clientname */ jack_session_command_t *jack_session_notify ( jack_client_t* client, const char *target, jack_session_event_type_t type, const char *path) JACK_WEAK_EXPORT; /** * Free the memory allocated by a session command. */ void jack_session_commands_free (jack_session_command_t *cmds) JACK_WEAK_EXPORT; /** * Reserve a client name and associate it with a UUID. * * When a client later calls jack_client_open() and specifies the UUID, jackd * will assign the reserved name. This allows a session manager to know in * advance under which client name its managed clients will appear. * * @return 0 on success, otherwise a non-zero error code */ int jack_reserve_client_name (jack_client_t *client, const char *name, const char *uuid) JACK_WEAK_EXPORT; /** * Find out whether a client has set up a session callback. * * @return 0 when the client has no session callback, 1 when it has one. * -1 on error. */ int jack_client_has_session_callback (jack_client_t *client, const char *client_name) JACK_WEAK_EXPORT; #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/common/jack/jslist.h0000644000000000000000000001263613214314510015231 0ustar rootroot/* Based on gslist.c from glib-1.2.9 (LGPL). Adaption to JACK, Copyright (C) 2002 Kai Vehmanen. - replaced use of gtypes with normal ANSI C types - glib's memory allocation routines replaced with malloc/free calls This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __jack_jslist_h__ #define __jack_jslist_h__ #include #include #ifdef sun #define __inline__ #endif typedef struct _JSList JSList; typedef int (*JCompareFunc) (void* a, void* b); struct _JSList { void *data; JSList *next; }; static __inline__ JSList* jack_slist_alloc (void) { JSList *new_list; new_list = (JSList*)malloc(sizeof(JSList)); if (new_list) { new_list->data = NULL; new_list->next = NULL; } return new_list; } static __inline__ JSList* jack_slist_prepend (JSList* list, void* data) { JSList *new_list; new_list = (JSList*)malloc(sizeof(JSList)); if (new_list) { new_list->data = data; new_list->next = list; } return new_list; } #define jack_slist_next(slist) ((slist) ? (((JSList *)(slist))->next) : NULL) static __inline__ JSList* jack_slist_last (JSList *list) { if (list) { while (list->next) list = list->next; } return list; } static __inline__ JSList* jack_slist_remove_link (JSList *list, JSList *link) { JSList *tmp; JSList *prev; prev = NULL; tmp = list; while (tmp) { if (tmp == link) { if (prev) prev->next = tmp->next; if (list == tmp) list = list->next; tmp->next = NULL; break; } prev = tmp; tmp = tmp->next; } return list; } static __inline__ void jack_slist_free (JSList *list) { while (list) { JSList *next = list->next; free(list); list = next; } } static __inline__ void jack_slist_free_1 (JSList *list) { if (list) { free(list); } } static __inline__ JSList* jack_slist_remove (JSList *list, void *data) { JSList *tmp; JSList *prev; prev = NULL; tmp = list; while (tmp) { if (tmp->data == data) { if (prev) prev->next = tmp->next; if (list == tmp) list = list->next; tmp->next = NULL; jack_slist_free (tmp); break; } prev = tmp; tmp = tmp->next; } return list; } static __inline__ unsigned int jack_slist_length (JSList *list) { unsigned int length; length = 0; while (list) { length++; list = list->next; } return length; } static __inline__ JSList* jack_slist_find (JSList *list, void *data) { while (list) { if (list->data == data) break; list = list->next; } return list; } static __inline__ JSList* jack_slist_copy (JSList *list) { JSList *new_list = NULL; if (list) { JSList *last; new_list = jack_slist_alloc (); new_list->data = list->data; last = new_list; list = list->next; while (list) { last->next = jack_slist_alloc (); last = last->next; last->data = list->data; list = list->next; } } return new_list; } static __inline__ JSList* jack_slist_append (JSList *list, void *data) { JSList *new_list; JSList *last; new_list = jack_slist_alloc (); new_list->data = data; if (list) { last = jack_slist_last (list); last->next = new_list; return list; } else return new_list; } static __inline__ JSList* jack_slist_sort_merge (JSList *l1, JSList *l2, JCompareFunc compare_func) { JSList list, *l; l = &list; while (l1 && l2) { if (compare_func(l1->data, l2->data) < 0) { l = l->next = l1; l1 = l1->next; } else { l = l->next = l2; l2 = l2->next; } } l->next = l1 ? l1 : l2; return list.next; } static __inline__ JSList* jack_slist_sort (JSList *list, JCompareFunc compare_func) { JSList *l1, *l2; if (!list) return NULL; if (!list->next) return list; l1 = list; l2 = list->next; while ((l2 = l2->next) != NULL) { if ((l2 = l2->next) == NULL) break; l1 = l1->next; } l2 = l1->next; l1->next = NULL; return jack_slist_sort_merge (jack_slist_sort (list, compare_func), jack_slist_sort (l2, compare_func), compare_func); } #endif /* __jack_jslist_h__ */ 1.9.12~dfsg/common/jack/weakjack.h0000644000000000000000000001236413214314510015477 0ustar rootroot/* Copyright (C) 2010 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __weakjack_h__ #define __weakjack_h__ /** * @defgroup WeakLinkage Managing support for newer/older versions of JACK * @{ One challenge faced by developers is that of taking * advantage of new features introduced in new versions * of [ JACK ] while still supporting older versions of * the system. Normally, if an application uses a new * feature in a library/API, it is unable to run on * earlier versions of the library/API that do not * support that feature. Such applications would either * fail to launch or crash when an attempt to use the * feature was made. This problem cane be solved using * weakly-linked symbols. * * When a symbol in a framework is defined as weakly * linked, the symbol does not have to be present at * runtime for a process to continue running. The static * linker identifies a weakly linked symbol as such in * any code module that references the symbol. The * dynamic linker uses this same information at runtime * to determine whether a process can continue * running. If a weakly linked symbol is not present in * the framework, the code module can continue to run as * long as it does not reference the symbol. However, if * the symbol is present, the code can use it normally. * * (adapted from: http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html) * * A concrete example will help. Suppose that someone uses a version * of a JACK client we'll call "Jill". Jill was linked against a version * of JACK that contains a newer part of the API (say, jack_set_latency_callback()) * and would like to use it if it is available. * * When Jill is run on a system that has a suitably "new" version of * JACK, this function will be available entirely normally. But if Jill * is run on a system with an old version of JACK, the function isn't * available. * * With normal symbol linkage, this would create a startup error whenever * someone tries to run Jill with the "old" version of JACK. However, functions * added to JACK after version 0.116.2 are all declared to have "weak" linkage * which means that their abscence doesn't cause an error during program * startup. Instead, Jill can test whether or not the symbol jack_set_latency_callback * is null or not. If its null, it means that the JACK installed on this machine * is too old to support this function. If its not null, then Jill can use it * just like any other function in the API. For example: * * \code * if (jack_set_latency_callback) { * jack_set_latency_callback (jill_client, jill_latency_callback, arg); * } * \endcode * * However, there are clients that may want to use this approach to parts of the * the JACK API that predate 0.116.2. For example, they might want to see if even * really old basic parts of the API like jack_client_open() exist at runtime. * * Such clients should include before any other JACK header. * This will make the \b entire JACK API be subject to weak linkage, so that any * and all functions can be checked for existence at runtime. It is important * to understand that very few clients need to do this - if you use this * feature you should have a clear reason to do so. * * */ #ifdef __APPLE__ #define WEAK_ATTRIBUTE weak_import #else #define WEAK_ATTRIBUTE __weak__ #endif #ifndef JACK_OPTIONAL_WEAK_EXPORT /* JACK_OPTIONAL_WEAK_EXPORT needs to be a macro which expands into a compiler directive. If non-null, the directive must tell the compiler to arrange for weak linkage of the symbol it used with. For this to work fully may require linker arguments for the client as well. */ #ifdef __GNUC__ #define JACK_OPTIONAL_WEAK_EXPORT __attribute__((WEAK_ATTRIBUTE)) #else /* Add other things here for non-gcc platforms */ #endif #endif #ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT /* JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT needs to be a macro which expands into a compiler directive. If non-null, the directive must tell the compiler to arrange for weak linkage of the symbol it is used with AND optionally to mark the symbol as deprecated. For this to work fully may require linker arguments for the client as well. */ #ifdef __GNUC__ #define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((WEAK_ATTRIBUTE,__deprecated__)) #else /* Add other things here for non-gcc platforms */ #endif #endif /*@}*/ #endif /* weakjack */ 1.9.12~dfsg/common/jack/ringbuffer.h0000644000000000000000000001744113214314510016051 0ustar rootroot/* Copyright (C) 2000 Paul Davis Copyright (C) 2003 Rohan Drape This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _RINGBUFFER_H #define _RINGBUFFER_H #ifdef __cplusplus extern "C" { #endif #include /** @file ringbuffer.h * * A set of library functions to make lock-free ringbuffers available * to JACK clients. The `capture_client.c' (in the example_clients * directory) is a fully functioning user of this API. * * The key attribute of a ringbuffer is that it can be safely accessed * by two threads simultaneously -- one reading from the buffer and * the other writing to it -- without using any synchronization or * mutual exclusion primitives. For this to work correctly, there can * only be a single reader and a single writer thread. Their * identities cannot be interchanged. */ typedef struct { char *buf; size_t len; } jack_ringbuffer_data_t ; typedef struct { char *buf; volatile size_t write_ptr; volatile size_t read_ptr; size_t size; size_t size_mask; int mlocked; } jack_ringbuffer_t ; /** * Allocates a ringbuffer data structure of a specified size. The * caller must arrange for a call to jack_ringbuffer_free() to release * the memory associated with the ringbuffer. * * @param sz the ringbuffer size in bytes. * * @return a pointer to a new jack_ringbuffer_t, if successful; NULL * otherwise. */ jack_ringbuffer_t *jack_ringbuffer_create(size_t sz); /** * Frees the ringbuffer data structure allocated by an earlier call to * jack_ringbuffer_create(). * * @param rb a pointer to the ringbuffer structure. */ void jack_ringbuffer_free(jack_ringbuffer_t *rb); /** * Fill a data structure with a description of the current readable * data held in the ringbuffer. This description is returned in a two * element array of jack_ringbuffer_data_t. Two elements are needed * because the data to be read may be split across the end of the * ringbuffer. * * The first element will always contain a valid @a len field, which * may be zero or greater. If the @a len field is non-zero, then data * can be read in a contiguous fashion using the address given in the * corresponding @a buf field. * * If the second element has a non-zero @a len field, then a second * contiguous stretch of data can be read from the address given in * its corresponding @a buf field. * * @param rb a pointer to the ringbuffer structure. * @param vec a pointer to a 2 element array of jack_ringbuffer_data_t. * */ void jack_ringbuffer_get_read_vector(const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *vec); /** * Fill a data structure with a description of the current writable * space in the ringbuffer. The description is returned in a two * element array of jack_ringbuffer_data_t. Two elements are needed * because the space available for writing may be split across the end * of the ringbuffer. * * The first element will always contain a valid @a len field, which * may be zero or greater. If the @a len field is non-zero, then data * can be written in a contiguous fashion using the address given in * the corresponding @a buf field. * * If the second element has a non-zero @a len field, then a second * contiguous stretch of data can be written to the address given in * the corresponding @a buf field. * * @param rb a pointer to the ringbuffer structure. * @param vec a pointer to a 2 element array of jack_ringbuffer_data_t. */ void jack_ringbuffer_get_write_vector(const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *vec); /** * Read data from the ringbuffer. * * @param rb a pointer to the ringbuffer structure. * @param dest a pointer to a buffer where data read from the * ringbuffer will go. * @param cnt the number of bytes to read. * * @return the number of bytes read, which may range from 0 to cnt. */ size_t jack_ringbuffer_read(jack_ringbuffer_t *rb, char *dest, size_t cnt); /** * Read data from the ringbuffer. Opposed to jack_ringbuffer_read() * this function does not move the read pointer. Thus it's * a convenient way to inspect data in the ringbuffer in a * continous fashion. The price is that the data is copied * into a user provided buffer. For "raw" non-copy inspection * of the data in the ringbuffer use jack_ringbuffer_get_read_vector(). * * @param rb a pointer to the ringbuffer structure. * @param dest a pointer to a buffer where data read from the * ringbuffer will go. * @param cnt the number of bytes to read. * * @return the number of bytes read, which may range from 0 to cnt. */ size_t jack_ringbuffer_peek(jack_ringbuffer_t *rb, char *dest, size_t cnt); /** * Advance the read pointer. * * After data have been read from the ringbuffer using the pointers * returned by jack_ringbuffer_get_read_vector(), use this function to * advance the buffer pointers, making that space available for future * write operations. * * @param rb a pointer to the ringbuffer structure. * @param cnt the number of bytes read. */ void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt); /** * Return the number of bytes available for reading. * * @param rb a pointer to the ringbuffer structure. * * @return the number of bytes available to read. */ size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb); /** * Lock a ringbuffer data block into memory. * * Uses the mlock() system call. This is not a realtime operation. * * @param rb a pointer to the ringbuffer structure. */ int jack_ringbuffer_mlock(jack_ringbuffer_t *rb); /** * Reset the read and write pointers, making an empty buffer. * * This is not thread safe. * * @param rb a pointer to the ringbuffer structure. */ void jack_ringbuffer_reset(jack_ringbuffer_t *rb); /** * Reset the internal "available" size, and read and write pointers, making an empty buffer. * * This is not thread safe. * * @param rb a pointer to the ringbuffer structure. * @param sz the new size, that must be less than allocated size. */ void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz); /** * Write data into the ringbuffer. * * @param rb a pointer to the ringbuffer structure. * @param src a pointer to the data to be written to the ringbuffer. * @param cnt the number of bytes to write. * * @return the number of bytes write, which may range from 0 to cnt */ size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src, size_t cnt); /** * Advance the write pointer. * * After data have been written the ringbuffer using the pointers * returned by jack_ringbuffer_get_write_vector(), use this function * to advance the buffer pointer, making the data available for future * read operations. * * @param rb a pointer to the ringbuffer structure. * @param cnt the number of bytes written. */ void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt); /** * Return the number of bytes available for writing. * * @param rb a pointer to the ringbuffer structure. * * @return the amount of free space (in bytes) available for writing. */ size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/common/JackTransportEngine.h0000644000000000000000000001266013214314510016721 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackTransportEngine__ #define __JackTransportEngine__ #include "JackAtomicArrayState.h" #include "JackCompilerDeps.h" #include "types.h" namespace Jack { typedef enum { TransportCommandNone = 0, TransportCommandStart = 1, TransportCommandStop = 2, } transport_command_t; /*! \brief The client transport structure. We have: - a "current" position - a "pending" position prepared by the server at each cycle - a "request" position wanted by a client At the beginning of a cycle the server needs to select a new current position. When a request and a pending position are available, the request takes precedence on the pending one. The server atomically switches to the new position. The current position can be read by clients. We use a JackAtomicArrayState pattern that allows to manage several "next" states independantly. In jack1 implementation, transport code (jack_transport_cycle_end) was not called if the graph could not be locked (see jack_run_one_cycle). Here transport cycle (CycleBegin, CycleEnd) has to run in the RT thread concurrently with code executed from the "command" thread. Each client maintains a state in it's shared memory area defined by: - it's current transport state - a boolean that is "true" when slow-sync cb has to be called - a boolean that is "true" when timebase cb is called with new_pos on Several operations set the "slow-sync cb" flag to true: - setting a new cb (client) - activate (client) - transport start (server) - new pos (server) Slow-sync cb calls stops when: - the cb return true (client) - desactivate (client) - transport stop (server) Several operations set the "timebase cb" flag to true: - setting a new cb (client) - activate (client) - transport start (server) ?? - new pos (server) Timebase cb "new_pos" argument calls stops when: - after one cb call with "new_pos" argument true (client) - desactivate (client) - release (client) - transport stop (server) */ class JackClientInterface; PRE_PACKED_STRUCTURE class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState { private: jack_transport_state_t fTransportState; volatile transport_command_t fTransportCmd; transport_command_t fPreviousCmd; /* previous transport_cmd */ jack_time_t fSyncTimeout; int fSyncTimeLeft; int fTimeBaseMaster; bool fPendingPos; bool fNetworkSync; bool fConditionnal; SInt32 fWriteCounter; bool CheckAllRolling(JackClientInterface** table); void MakeAllStartingLocating(JackClientInterface** table); void MakeAllStopping(JackClientInterface** table); void MakeAllLocating(JackClientInterface** table); void SyncTimeout(jack_nframes_t frame_rate, jack_nframes_t buffer_size); public: JackTransportEngine(); ~JackTransportEngine() {} void SetCommand(transport_command_t state) { fTransportCmd = state; } jack_transport_state_t GetState() const { return fTransportState; } void SetState(jack_transport_state_t state) { fTransportState = state; } /* \brief */ int ResetTimebase(int refnum); /* \brief */ int SetTimebaseMaster(int refnum, bool conditionnal); void GetTimebaseMaster(int& refnum, bool& conditionnal) { refnum = fTimeBaseMaster; conditionnal = fConditionnal; } /* \brief */ void CycleBegin(jack_nframes_t frame_rate, jack_time_t time); /* \brief */ void CycleEnd(JackClientInterface** table, jack_nframes_t frame_rate, jack_nframes_t buffer_size); /* \brief */ void SetSyncTimeout(jack_time_t timeout) { fSyncTimeout = timeout; } void ReadCurrentPos(jack_position_t* pos); jack_unique_t GenerateUniqueID() { return (jack_unique_t)INC_ATOMIC(&fWriteCounter); } void RequestNewPos(jack_position_t* pos); jack_transport_state_t Query(jack_position_t* pos); jack_nframes_t GetCurrentFrame(); static void CopyPosition(jack_position_t* from, jack_position_t* to); bool GetNetworkSync() const { return fNetworkSync; } void SetNetworkSync(bool sync) { fNetworkSync = sync; } } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackNetDriver.h0000644000000000000000000000717513214314510015506 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackNetDriver__ #define __JackNetDriver__ #include "JackTimedDriver.h" #include "JackNetInterface.h" //#define JACK_MONITOR namespace Jack { /** \Brief This class describes the Net Backend */ class JackNetDriver : public JackWaiterDriver, public JackNetSlaveInterface { private: //jack data jack_port_id_t* fMidiCapturePortList; jack_port_id_t* fMidiPlaybackPortList; //transport int fLastTransportState; int fLastTimebaseMaster; // The wanted value at creation time (may be different than the value actually returned by the master) int fWantedAudioCaptureChannels; int fWantedAudioPlaybackChannels; int fWantedMIDICaptureChannels; int fWantedMIDIPlaybackChannels; bool fAutoSave; //monitoring #ifdef JACK_MONITOR JackGnuPlotMonitor* fNetTimeMon; jack_time_t fRcvSyncUst; #endif bool Initialize(); void FreeAll(); int AllocPorts(); int FreePorts(); //transport void EncodeTransportData(); void DecodeTransportData(); JackMidiBuffer* GetMidiInputBuffer(int port_index); JackMidiBuffer* GetMidiOutputBuffer(int port_index); void SaveConnections(int alias); void UpdateLatencies(); public: JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, char* net_name, uint transport_sync, int network_latency, int celt_encoding, int opus_encoding, bool auto_save); virtual ~JackNetDriver(); int Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); int Close(); int Attach(); int Detach(); int Read(); int Write(); // BufferSize can't be changed bool IsFixedBufferSize() { return true; } int SetBufferSize(jack_nframes_t buffer_size) { return -1; } int SetSampleRate(jack_nframes_t sample_rate) { return -1; } }; } #endif 1.9.12~dfsg/common/JackMidiBufferReadQueue.cpp0000644000000000000000000000410013214314510017735 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMidiBufferReadQueue.h" #include "JackMidiUtil.h" #include "JackError.h" using Jack::JackMidiBufferReadQueue; JackMidiBufferReadQueue::JackMidiBufferReadQueue() { event_count = 0; index = 0; } jack_midi_event_t * JackMidiBufferReadQueue::DequeueEvent() { jack_midi_event_t *e = 0; if (index < event_count) { JackMidiEvent *event = &(buffer->events[index]); midi_event.buffer = event->GetData(buffer); midi_event.size = event->size; midi_event.time = last_frame_time + event->time; e = &midi_event; index++; } return e; } void JackMidiBufferReadQueue::ResetMidiBuffer(JackMidiBuffer *buffer) { event_count = 0; index = 0; if (! buffer) { jack_error("JackMidiBufferReadQueue::ResetMidiBuffer - buffer reset " "to NULL"); } else if (! buffer->IsValid()) { jack_error("JackMidiBufferReadQueue::ResetMidiBuffer - buffer reset " "to invalid buffer"); } else { uint32_t lost_events = buffer->lost_events; if (lost_events) { jack_error("JackMidiBufferReadQueue::ResetMidiBuffer - %d events " "lost during mixdown", lost_events); } this->buffer = buffer; event_count = buffer->event_count; last_frame_time = GetLastFrame(); } } 1.9.12~dfsg/common/JackWaitCallbackDriver.h0000644000000000000000000000247413214314510017276 0ustar rootroot/* Copyright (C) 2014 Cédric Schieli This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __JackWaitCallbackDriver__ #define __JackWaitCallbackDriver__ #include "JackWaitThreadedDriver.h" namespace Jack { /*! \brief Wrapper for a restartable non-threaded driver (e.g. JackProxyDriver). Simply ends its thread when the decorated driver Initialize method returns. Self register with the supplied JackRestarterDriver so it can restart the thread. */ class SERVER_EXPORT JackWaitCallbackDriver : public JackWaitThreadedDriver { public: JackWaitCallbackDriver(JackRestarterDriver* driver); protected: bool ExecuteReal(); }; } // end of namespace #endif 1.9.12~dfsg/common/JackConstants.h0000644000000000000000000000477013214314510015556 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackConstants__ #define __JackConstants__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define VERSION "1.9.12" #define BUFFER_SIZE_MAX 8192 #define JACK_PORT_NAME_SIZE 256 #define JACK_PORT_TYPE_SIZE 32 #define JACK_SERVER_NAME_SIZE 256 #define JACK_CLIENT_NAME_SIZE 64 #define JACK_MESSAGE_SIZE 256 #define JACK_UUID_SIZE 36 // to match jack1 and uuid.h #define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */ #define JACK_SESSION_COMMAND_SIZE 256 #define SYNC_MAX_NAME_SIZE 256 #define REAL_JACK_PORT_NAME_SIZE JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE // full name like "client_name:short_port_name" #ifndef PORT_NUM #define PORT_NUM 2048 #endif #ifndef PORT_NUM_MAX #define PORT_NUM_MAX 4096 // The "max" value for ports used in connection manager, although port number in graph manager is dynamic #endif #define DRIVER_PORT_NUM 256 #ifndef PORT_NUM_FOR_CLIENT #define PORT_NUM_FOR_CLIENT 768 #endif #define FIRST_AVAILABLE_PORT 1 #define CONNECTION_NUM_FOR_PORT PORT_NUM_FOR_CLIENT #ifndef CLIENT_NUM #define CLIENT_NUM 64 #endif #define AUDIO_DRIVER_REFNUM 0 // Audio driver is initialized first, it will get the refnum 0 #define FREEWHEEL_DRIVER_REFNUM 1 // Freewheel driver is initialized second, it will get the refnum 1 #define JACK_DEFAULT_SERVER_NAME "default" #define ALL_CLIENTS -1 // for notification #define JACK_PROTOCOL_VERSION 8 #define SOCKET_TIME_OUT 2 // in sec #define DRIVER_OPEN_TIMEOUT 5 // in sec #define FREEWHEEL_DRIVER_TIMEOUT 10 // in sec #define DRIVER_TIMEOUT_FACTOR 10 #define JACK_SERVER_FAILURE "JACK server has been closed" #define NO_PORT 0xFFFE #define EMPTY 0xFFFD #define FREE 0xFFFC #define JACK_DEFAULT_SELF_CONNECT_MODE ' ' /* allow all requests */ #endif 1.9.12~dfsg/common/JackLibClient.cpp0000644000000000000000000001413713214314510016000 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackLibClient.h" #include "JackTime.h" #include "JackLibGlobals.h" #include "JackGlobals.h" #include "JackPlatformPlug.h" #include "JackTools.h" namespace Jack { // Used for external C API (JackAPI.cpp) JackGraphManager* GetGraphManager() { if (JackLibGlobals::fGlobals) { return JackLibGlobals::fGlobals->fGraphManager; } else { return NULL; } } JackEngineControl* GetEngineControl() { if (JackLibGlobals::fGlobals) { return JackLibGlobals::fGlobals->fEngineControl; } else { return NULL; } } JackSynchro* GetSynchroTable() { return (JackLibGlobals::fGlobals ? JackLibGlobals::fGlobals->fSynchroTable : 0); } //------------------- // Client management //------------------- /* ShutDown is called: - from the RT thread when Execute method fails - possibly from a "closed" notification channel (Not needed since the synch object used (Sema of Fifo will fails when server quits... see ShutDown)) */ void JackLibClient::ShutDown(jack_status_t code, const char* message) { jack_log("JackLibClient::ShutDown"); JackGlobals::fServerRunning = false; JackClient::ShutDown(code, message); } JackLibClient::JackLibClient(JackSynchro* table): JackClient(table) { jack_log("JackLibClient::JackLibClient table = %x", table); fChannel = new JackClientChannel(); } JackLibClient::~JackLibClient() { jack_log("JackLibClient::~JackLibClient"); delete fChannel; } int JackLibClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int shared_engine, shared_client, shared_graph, result; bool res; jack_log("JackLibClient::Open name = %s", name); if (strlen(name) >= JACK_CLIENT_NAME_SIZE) { jack_error("\"%s\" is too long to be used as a JACK client name.\n" "Please use %lu characters or less", name, JACK_CLIENT_NAME_SIZE - 1); return -1; } strncpy(fServerName, server_name, sizeof(fServerName)); // Open server/client channel char name_res[JACK_CLIENT_NAME_SIZE+1]; if (fChannel->Open(server_name, name, uuid, name_res, this, options, status) < 0) { jack_error("Cannot connect to the server"); goto error; } // Start receiving notifications if (fChannel->Start() < 0) { jack_error("Cannot start channel"); goto error; } // Require new client fChannel->ClientOpen(name_res, JackTools::GetPID(), uuid, &shared_engine, &shared_client, &shared_graph, &result); if (result < 0) { jack_error("Cannot open %s client", name_res); goto error; } try { // Map shared memory segments JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName); JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName); fClientControl.SetShmIndex(shared_client, fServerName); JackGlobals::fVerbose = GetEngineControl()->fVerbose; } catch (...) { jack_error("Map shared memory segments exception"); goto error; } SetupDriverSync(false); // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process assert(JackGlobals::fSynchroMutex); JackGlobals::fSynchroMutex->Lock(); res = fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName); JackGlobals::fSynchroMutex->Unlock(); if (!res) { jack_error("Cannot ConnectSemaphore %s client", name_res); goto error; } JackGlobals::fClientTable[GetClientControl()->fRefNum] = this; SetClockSource(GetEngineControl()->fClockSource); jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum); return 0; error: fChannel->Stop(); fChannel->Close(); return -1; } // Notifications received from the server // TODO this should be done once for all clients in the process, when a shared notification channel // will be shared by all clients... int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int res = 0; assert(JackGlobals::fSynchroMutex); JackGlobals::fSynchroMutex->Lock(); // Done all time switch (notify) { case kAddClient: jack_log("JackClient::AddClient name = %s, ref = %ld ", name, refnum); // the synchro must be usable in I/O mode when several clients live in the same process res = fSynchroTable[refnum].Connect(name, fServerName) ? 0 : -1; break; case kRemoveClient: jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum); if (GetClientControl() && strcmp(GetClientControl()->fName, name) != 0) { res = fSynchroTable[refnum].Disconnect() ? 0 : -1; } break; } JackGlobals::fSynchroMutex->Unlock(); return res; } JackGraphManager* JackLibClient::GetGraphManager() const { assert(JackLibGlobals::fGlobals->fGraphManager); return JackLibGlobals::fGlobals->fGraphManager; } JackEngineControl* JackLibClient::GetEngineControl() const { assert(JackLibGlobals::fGlobals->fEngineControl); return JackLibGlobals::fGlobals->fEngineControl; } JackClientControl* JackLibClient::GetClientControl() const { return fClientControl; } } // end of namespace 1.9.12~dfsg/common/JackGlobals.h0000644000000000000000000000361013214314510015155 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackGlobals__ #define __JackGlobals__ #include "JackPlatformPlug.h" #include "JackSystemDeps.h" #include "JackConstants.h" #ifdef __CLIENTDEBUG__ #include #include #include #include #endif namespace Jack { // Globals used for client management on server or library side. struct JackGlobals { static jack_tls_key fRealTimeThread; static jack_tls_key fNotificationThread; static jack_tls_key fKeyLogFunction; static JackMutex* fOpenMutex; static JackMutex* fSynchroMutex; static volatile bool fServerRunning; static JackClient* fClientTable[CLIENT_NUM]; static bool fVerbose; #ifndef WIN32 static jack_thread_creator_t fJackThreadCreator; #endif #ifdef __CLIENTDEBUG__ static std::ofstream* fStream; #endif static void CheckContext(const char* name); }; // Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. extern SERVER_EXPORT JackGraphManager* GetGraphManager(); extern SERVER_EXPORT JackEngineControl* GetEngineControl(); extern SERVER_EXPORT JackSynchro* GetSynchroTable(); } // end of namespace #endif 1.9.12~dfsg/common/JackMidiRawInputWriteQueue.cpp0000644000000000000000000002073013214314510020523 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "JackMidiRawInputWriteQueue.h" #include "JackError.h" using Jack::JackMidiRawInputWriteQueue; JackMidiRawInputWriteQueue:: JackMidiRawInputWriteQueue(JackMidiWriteQueue *write_queue, size_t max_packet_data, size_t max_packets) { packet_queue = new JackMidiAsyncQueue(max_packet_data, max_packets); std::auto_ptr packet_queue_ptr(packet_queue); input_buffer = new jack_midi_data_t[max_packet_data]; Clear(); expected_bytes = 0; event_pending = false; input_buffer_size = max_packet_data; packet = 0; status_byte = 0; this->write_queue = write_queue; packet_queue_ptr.release(); } JackMidiRawInputWriteQueue::~JackMidiRawInputWriteQueue() { delete[] input_buffer; delete packet_queue; } void JackMidiRawInputWriteQueue::Clear() { total_bytes = 0; unbuffered_bytes = 0; } Jack::JackMidiWriteQueue::EnqueueResult JackMidiRawInputWriteQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) { return packet_queue->EnqueueEvent(time, size, buffer); } size_t JackMidiRawInputWriteQueue::GetAvailableSpace() { return packet_queue->GetAvailableSpace(); } void JackMidiRawInputWriteQueue::HandleBufferFailure(size_t unbuffered_bytes, size_t total_bytes) { jack_error("JackMidiRawInputWriteQueue::HandleBufferFailure - %d MIDI " "byte(s) of a %d byte message could not be buffered. The " "message has been dropped.", unbuffered_bytes, total_bytes); } void JackMidiRawInputWriteQueue::HandleEventLoss(jack_midi_event_t *event) { jack_error("JackMidiRawInputWriteQueue::HandleEventLoss - A %d byte MIDI " "event scheduled for frame '%d' could not be processed because " "the write queue cannot accomodate an event of that size. The " "event has been discarded.", event->size, event->time); } void JackMidiRawInputWriteQueue::HandleIncompleteMessage(size_t total_bytes) { jack_error("JackMidiRawInputWriteQueue::HandleIncompleteMessage - " "Discarding %d MIDI byte(s) of an incomplete message. The " "MIDI cable may have been unplugged.", total_bytes); } void JackMidiRawInputWriteQueue::HandleInvalidStatusByte(jack_midi_data_t byte) { jack_error("JackMidiRawInputWriteQueue::HandleInvalidStatusByte - " "Dropping invalid MIDI status byte '%x'.", (unsigned int) byte); } void JackMidiRawInputWriteQueue::HandleUnexpectedSysexEnd(size_t total_bytes) { jack_error("JackMidiRawInputWriteQueue::HandleUnexpectedSysexEnd - " "Received a sysex end byte without first receiving a sysex " "start byte. Discarding %d MIDI byte(s). The cable may have " "been unplugged.", total_bytes); } bool JackMidiRawInputWriteQueue::PrepareBufferedEvent(jack_nframes_t time) { bool result = ! unbuffered_bytes; if (! result) { HandleBufferFailure(unbuffered_bytes, total_bytes); } else { PrepareEvent(time, total_bytes, input_buffer); } Clear(); if (status_byte >= 0xf0) { expected_bytes = 0; status_byte = 0; } return result; } bool JackMidiRawInputWriteQueue::PrepareByteEvent(jack_nframes_t time, jack_midi_data_t byte) { event_byte = byte; PrepareEvent(time, 1, &event_byte); return true; } void JackMidiRawInputWriteQueue::PrepareEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) { event.buffer = buffer; event.size = size; event.time = time; event_pending = true; } jack_nframes_t JackMidiRawInputWriteQueue::Process(jack_nframes_t boundary_frame) { if (event_pending) { if (! WriteEvent(boundary_frame)) { return event.time; } } if (! packet) { packet = packet_queue->DequeueEvent(); } for (; packet; packet = packet_queue->DequeueEvent()) { for (; packet->size; (packet->buffer)++, (packet->size)--) { if (ProcessByte(packet->time, *(packet->buffer))) { if (! WriteEvent(boundary_frame)) { (packet->buffer)++; (packet->size)--; return event.time; } } } } return 0; } bool JackMidiRawInputWriteQueue::ProcessByte(jack_nframes_t time, jack_midi_data_t byte) { if (byte >= 0xf8) { // Realtime if (byte == 0xfd) { HandleInvalidStatusByte(byte); return false; } return PrepareByteEvent(time, byte); } if (byte == 0xf7) { // Sysex end if (status_byte == 0xf0) { RecordByte(byte); return PrepareBufferedEvent(time); } HandleUnexpectedSysexEnd(total_bytes); Clear(); expected_bytes = 0; status_byte = 0; return false; } if (byte >= 0x80) { // Non-realtime status byte if (total_bytes) { HandleIncompleteMessage(total_bytes); Clear(); } status_byte = byte; switch (byte & 0xf0) { case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: // Note On, Note Off, Aftertouch, Control Change, Pitch Wheel expected_bytes = 3; break; case 0xc0: case 0xd0: // Program Change, Channel Pressure expected_bytes = 2; break; case 0xf0: switch (byte) { case 0xf0: // Sysex expected_bytes = 0; break; case 0xf1: case 0xf3: // MTC Quarter Frame, Song Select expected_bytes = 2; break; case 0xf2: // Song Position expected_bytes = 3; break; case 0xf4: case 0xf5: // Undefined HandleInvalidStatusByte(byte); expected_bytes = 0; status_byte = 0; return false; case 0xf6: // Tune Request bool result = PrepareByteEvent(time, byte); if (result) { expected_bytes = 0; status_byte = 0; } return result; } } RecordByte(byte); return false; } // Data byte if (! status_byte) { // Data bytes without a status will be discarded. total_bytes++; unbuffered_bytes++; return false; } if (! total_bytes) { // Apply running status. RecordByte(status_byte); } RecordByte(byte); return (total_bytes == expected_bytes) ? PrepareBufferedEvent(time) : false; } void JackMidiRawInputWriteQueue::RecordByte(jack_midi_data_t byte) { if (total_bytes < input_buffer_size) { input_buffer[total_bytes] = byte; } else { unbuffered_bytes++; } total_bytes++; } bool JackMidiRawInputWriteQueue::WriteEvent(jack_nframes_t boundary_frame) { if ((! boundary_frame) || (event.time < boundary_frame)) { switch (write_queue->EnqueueEvent(&event)) { case BUFFER_TOO_SMALL: HandleEventLoss(&event); // Fallthrough on purpose case OK: event_pending = false; return true; default: // This is here to stop compilers from warning us about not // handling enumeration values. ; } } return false; } 1.9.12~dfsg/common/JackMidiAsyncWaitQueue.cpp0000644000000000000000000000554013214314510017643 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "JackMidiAsyncWaitQueue.h" #include "JackMidiUtil.h" #include "JackTime.h" using Jack::JackMidiAsyncWaitQueue; JackMidiAsyncWaitQueue::JackMidiAsyncWaitQueue(size_t max_bytes, size_t max_messages): JackMidiAsyncQueue(max_bytes, max_messages) { if (semaphore.Allocate("JackMidiAsyncWaitQueue", "midi-thread", 0)) { throw std::bad_alloc(); } } JackMidiAsyncWaitQueue::~JackMidiAsyncWaitQueue() { semaphore.Destroy(); } jack_midi_event_t * JackMidiAsyncWaitQueue::DequeueEvent() { return DequeueEvent((long) 0); } jack_midi_event_t * JackMidiAsyncWaitQueue::DequeueEvent(jack_nframes_t frame) { // XXX: I worry about timer resolution on Solaris and Windows. When the // resolution for the `JackSynchro` object is milliseconds, the worst-case // scenario for processor objects is that the wait time becomes less than a // millisecond, and the processor object continually calls this method, // expecting to wait a certain amount of microseconds, and ends up not // waiting at all each time, essentially busy-waiting until the current // frame is reached. Perhaps there should be a #define that indicates the // wait time resolution for `JackSynchro` objects so that we can wait a // little longer if necessary. jack_time_t frame_time = GetTimeFromFrames(frame); jack_time_t current_time = GetMicroSeconds(); return DequeueEvent((frame_time < current_time) ? 0 : (long) (frame_time - current_time)); } jack_midi_event_t * JackMidiAsyncWaitQueue::DequeueEvent(long usec) { return ((usec < 0) ? semaphore.Wait() : semaphore.TimedWait(usec)) ? JackMidiAsyncQueue::DequeueEvent() : 0; } Jack::JackMidiWriteQueue::EnqueueResult JackMidiAsyncWaitQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) { EnqueueResult result = JackMidiAsyncQueue::EnqueueEvent(time, size, buffer); if (result == OK) { semaphore.Signal(); } return result; } 1.9.12~dfsg/common/JackInternalClient.h0000644000000000000000000000667413214314510016522 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackInternalClient__ #define __JackInternalClient__ #include "JackClient.h" #include "JackClientControl.h" #include "driver_interface.h" namespace Jack { struct JackEngineControl; /*! \brief Internal clients in the server. */ class JackInternalClient : public JackClient { private: JackClientControl fClientControl; /*! Client control */ public: JackInternalClient(JackServer* server, JackSynchro* table); virtual ~JackInternalClient(); int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); void ShutDown(jack_status_t code, const char* message); JackGraphManager* GetGraphManager() const; JackEngineControl* GetEngineControl() const; JackClientControl* GetClientControl() const; static JackGraphManager* fGraphManager; /*! Shared memory Port manager */ static JackEngineControl* fEngineControl; /*! Shared engine cotrol */ }; /*! \brief Loadable internal clients in the server. */ typedef int (*InitializeCallback)(jack_client_t*, const char*); typedef int (*InternalInitializeCallback)(jack_client_t*, const JSList* params); typedef void (*FinishCallback)(void *); class JackLoadableInternalClient : public JackInternalClient { protected: JACK_HANDLE fHandle; FinishCallback fFinish; JackDriverDescFunction fDescriptor; public: JackLoadableInternalClient(JackServer* server, JackSynchro* table) :JackInternalClient(server, table), fHandle(NULL), fFinish(NULL), fDescriptor(NULL) {} virtual ~JackLoadableInternalClient(); virtual int Init(const char* so_name); }; class JackLoadableInternalClient1 : public JackLoadableInternalClient { private: InitializeCallback fInitialize; char fObjectData[JACK_LOAD_INIT_LIMIT]; public: JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data); virtual ~JackLoadableInternalClient1() {} int Init(const char* so_name); int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); }; class JackLoadableInternalClient2 : public JackLoadableInternalClient { private: InternalInitializeCallback fInitialize; const JSList* fParameters; public: JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters); virtual ~JackLoadableInternalClient2() {} int Init(const char* so_name); int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); }; } // end of namespace #endif 1.9.12~dfsg/common/JackServerGlobals.h0000644000000000000000000000374013214314510016350 0ustar rootroot/* Copyright (C) 2005 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackServerGlobals__ #define __JackServerGlobals__ #include "driver_interface.h" #include "JackDriverLoader.h" #include "JackCompilerDeps.h" #include "JackServer.h" #include namespace Jack { class JackClient; /*! \brief Global server static structure: singleton kind of pattern. */ struct SERVER_EXPORT JackServerGlobals { static JackServer* fInstance; static unsigned int fUserCount; static std::map fSlavesList; static std::map fInternalsList; static bool (* on_device_acquire)(const char* device_name); static void (* on_device_release)(const char* device_name); JackServerGlobals(); ~JackServerGlobals(); static bool Init(); static void Destroy(); static int Start(const char* server_name, jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, int temporary, int time_out_ms, int rt, int priority, int port_max, int verbose, jack_timer_type_t clock, char self_connect_mode); static void Stop(); static void Delete(); }; } // end of namespace #endif 1.9.12~dfsg/common/JackMutex.h0000644000000000000000000000344213214314510014677 0ustar rootroot/* Copyright (C) 2006 Grame This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France grame@grame.fr */ #ifndef __JackMutex__ #define __JackMutex__ #include #include "JackError.h" #include "JackPlatformPlug.h" namespace Jack { /*! \brief Base class for "lockable" objects. */ class JackLockAble { protected: JackMutex fMutex; JackLockAble(const char* name = NULL) :fMutex(name) {} ~JackLockAble() {} public: bool Lock() { return fMutex.Lock(); } bool Trylock() { return fMutex.Trylock(); } bool Unlock() { return fMutex.Unlock(); } }; class JackLock { private: JackLockAble* fObj; public: JackLock(JackLockAble* obj): fObj(obj) { fObj->Lock(); } JackLock(const JackLockAble* obj): fObj((JackLockAble*)obj) { fObj->Lock(); } ~JackLock() { fObj->Unlock(); } }; } // namespace #endif 1.9.12~dfsg/common/JackClientControl.h0000644000000000000000000000524013214314510016352 0ustar rootroot/* Copyright (C) 2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackClientControl__ #define __JackClientControl__ #include "JackShmMem.h" #include "JackPort.h" #include "JackSynchro.h" #include "JackNotification.h" #include "JackSession.h" namespace Jack { /*! \brief Client control possibly in shared memory. */ PRE_PACKED_STRUCTURE struct JackClientControl : public JackShmMemAble { char fName[JACK_CLIENT_NAME_SIZE + 1]; bool fCallback[kMaxNotification]; volatile jack_transport_state_t fTransportState; volatile bool fTransportSync; /* Will be true when slow-sync cb has to be called */ volatile bool fTransportTimebase; /* Will be true when timebase cb is called with new_pos on */ int fRefNum; int fPID; bool fActive; int fSessionID; char fSessionCommand[JACK_SESSION_COMMAND_SIZE]; jack_session_flags_t fSessionFlags; JackClientControl(const char* name, int pid, int refnum, int uuid) { Init(name, pid, refnum, uuid); } JackClientControl(const char* name) { Init(name, 0, -1, -1); } JackClientControl() { Init("", 0, -1, -1); } void Init(const char* name, int pid, int refnum, int uuid) { strcpy(fName, name); for (int i = 0; i < kMaxNotification; i++) { fCallback[i] = false; } // Always activated fCallback[kAddClient] = true; fCallback[kRemoveClient] = true; fCallback[kActivateClient] = true; fCallback[kLatencyCallback] = true; // So that driver synchro are correctly setup in "flush" or "normal" mode fCallback[kStartFreewheelCallback] = true; fCallback[kStopFreewheelCallback] = true; fRefNum = refnum; fPID = pid; fTransportState = JackTransportStopped; fTransportSync = false; fTransportTimebase = false; fActive = false; fSessionID = uuid; } } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackNetSocket.h0000644000000000000000000000235713214314510015500 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackNetSocket__ #define __JackNetSocket__ #include "JackCompilerDeps.h" #include #include #include #include namespace Jack { //get host name********************************* SERVER_EXPORT int GetHostName(char * name, int size); //net errors *********************************** enum _net_error { NET_CONN_ERROR = 10000, NET_OP_ERROR, NET_NO_DATA, NET_NO_NETWORK, NET_NO_ERROR }; typedef enum _net_error net_error_t; } #endif 1.9.12~dfsg/common/JackClient.h0000644000000000000000000002041513214314510015012 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackClient__ #define __JackClient__ #include "JackClientInterface.h" #include "JackThread.h" #include "JackConstants.h" #include "JackSynchro.h" #include "JackPlatformPlug.h" #include "JackChannel.h" #include "JackRequest.h" #include "varargs.h" #include namespace Jack { class JackGraphManager; class JackServer; class JackEngine; struct JackClientControl; struct JackEngineControl; /*! \brief The base class for clients: share part of the implementation for JackInternalClient and JackLibClient. */ class SERVER_EXPORT JackClient : public JackClientInterface, public JackRunnableInterface { friend class JackDebugClient; protected: JackProcessCallback fProcess; JackGraphOrderCallback fGraphOrder; JackXRunCallback fXrun; JackShutdownCallback fShutdown; JackInfoShutdownCallback fInfoShutdown; JackThreadInitCallback fInit; JackBufferSizeCallback fBufferSize; JackSampleRateCallback fSampleRate; JackClientRegistrationCallback fClientRegistration; JackFreewheelCallback fFreewheel; JackPortRegistrationCallback fPortRegistration; JackPortConnectCallback fPortConnect; JackPortRenameCallback fPortRename; JackTimebaseCallback fTimebase; JackSyncCallback fSync; JackThreadCallback fThreadFun; JackSessionCallback fSession; JackLatencyCallback fLatency; void* fProcessArg; void* fGraphOrderArg; void* fXrunArg; void* fShutdownArg; void* fInfoShutdownArg; void* fInitArg; void* fBufferSizeArg; void* fSampleRateArg; void* fClientRegistrationArg; void* fFreewheelArg; void* fPortRegistrationArg; void* fPortConnectArg; void* fPortRenameArg; void* fTimebaseArg; void* fSyncArg; void* fThreadFunArg; void* fSessionArg; void* fLatencyArg; char fServerName[JACK_SERVER_NAME_SIZE+1]; JackThread fThread; /*! Thread to execute the Process function */ detail::JackClientChannelInterface* fChannel; JackSynchro* fSynchroTable; std::list fPortList; JackSessionReply fSessionReply; int StartThread(); void SetupDriverSync(bool freewheel); bool IsActive(); void CallSyncCallback(); void CallTimebaseCallback(); virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value); inline void DummyCycle(); inline void ExecuteThread(); inline bool WaitSync(); inline void SignalSync(); inline int CallProcessCallback(); inline void End(); inline void Error(); inline jack_nframes_t CycleWaitAux(); inline void CycleSignalAux(int status); inline void CallSyncCallbackAux(); inline void CallTimebaseCallbackAux(); inline int ActivateAux(); inline void InitAux(); inline void SetupRealTime(); int HandleLatencyCallback(int status); public: JackClient(JackSynchro* table); virtual ~JackClient(); virtual int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) = 0; virtual int Close(); virtual JackGraphManager* GetGraphManager() const = 0; virtual JackEngineControl* GetEngineControl() const = 0; // Notifications virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual int Activate(); virtual int Deactivate(); // Context virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetFreeWheel(int onoff); virtual int ComputeTotalLatencies(); virtual void ShutDown(jack_status_t code, const char* message); virtual jack_native_thread_t GetThreadID(); // Port management virtual int PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size); virtual int PortUnRegister(jack_port_id_t port); virtual int PortConnect(const char* src, const char* dst); virtual int PortDisconnect(const char* src, const char* dst); virtual int PortDisconnect(jack_port_id_t src); virtual int PortIsMine(jack_port_id_t port_index); virtual int PortRename(jack_port_id_t port_index, const char* name); // Transport virtual int ReleaseTimebase(); virtual int SetSyncCallback(JackSyncCallback sync_callback, void* arg); virtual int SetSyncTimeout(jack_time_t timeout); virtual int SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg); virtual void TransportLocate(jack_nframes_t frame); virtual jack_transport_state_t TransportQuery(jack_position_t* pos); virtual jack_nframes_t GetCurrentTransportFrame(); virtual int TransportReposition(const jack_position_t* pos); virtual void TransportStart(); virtual void TransportStop(); // Callbacks virtual void OnShutdown(JackShutdownCallback callback, void *arg); virtual void OnInfoShutdown(JackInfoShutdownCallback callback, void *arg); virtual int SetProcessCallback(JackProcessCallback callback, void* arg); virtual int SetXRunCallback(JackXRunCallback callback, void* arg); virtual int SetInitCallback(JackThreadInitCallback callback, void* arg); virtual int SetGraphOrderCallback(JackGraphOrderCallback callback, void* arg); virtual int SetBufferSizeCallback(JackBufferSizeCallback callback, void* arg); virtual int SetSampleRateCallback(JackBufferSizeCallback callback, void* arg); virtual int SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg); virtual int SetFreewheelCallback(JackFreewheelCallback callback, void* arg); virtual int SetPortRegistrationCallback(JackPortRegistrationCallback callback, void* arg); virtual int SetPortConnectCallback(JackPortConnectCallback callback, void *arg); virtual int SetPortRenameCallback(JackPortRenameCallback callback, void *arg); virtual int SetSessionCallback(JackSessionCallback callback, void *arg); virtual int SetLatencyCallback(JackLatencyCallback callback, void *arg); // Internal clients virtual char* GetInternalClientName(int ref); virtual int InternalClientHandle(const char* client_name, jack_status_t* status); virtual int InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va); virtual void InternalClientUnload(int ref, jack_status_t* status); // RT Thread jack_nframes_t CycleWait(); void CycleSignal(int status); virtual int SetProcessThread(JackThreadCallback fun, void *arg); // Session API virtual jack_session_command_t* SessionNotify(const char* target, jack_session_event_type_t type, const char* path); virtual int SessionReply(jack_session_event_t* ev); virtual char* GetUUIDForClientName(const char* client_name); virtual char* GetClientNameByUUID(const char* uuid); virtual int ReserveClientName(const char* client_name, const char* uuid); virtual int ClientHasSessionCallback(const char* client_name); // JackRunnableInterface interface bool Init(); bool Execute(); }; } // end of namespace #endif 1.9.12~dfsg/common/JackMidiRawOutputWriteQueue.h0000644000000000000000000001201113214314510020362 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiRawOutputWriteQueue__ #define __JackMidiRawOutputWriteQueue__ #include "JackMidiAsyncQueue.h" #include "JackMidiSendQueue.h" namespace Jack { /** * This queue enqueues valid MIDI events and modifies them for raw output * to a write queue. It has a couple of advantages over straight MIDI * event copying: * * -Running status: Status bytes can be omitted when the status byte of the * current MIDI message is the same as the status byte of the last sent * MIDI message. * * -Realtime messages: Realtime messages are given priority over * non-realtime messages. Realtime bytes are interspersed with * non-realtime bytes so that realtime messages can be sent as close as * possible to the time they're scheduled for sending. * * Use this queue if the MIDI API you're interfacing with allows you to * send raw MIDI bytes. */ class SERVER_EXPORT JackMidiRawOutputWriteQueue: public JackMidiWriteQueue { private: jack_midi_event_t *non_rt_event; jack_nframes_t non_rt_event_time; JackMidiAsyncQueue *non_rt_queue; jack_midi_event_t *rt_event; jack_nframes_t rt_event_time; JackMidiAsyncQueue *rt_queue; jack_midi_data_t running_status; JackMidiSendQueue *send_queue; void DequeueNonRealtimeEvent(); void DequeueRealtimeEvent(); bool SendByte(jack_nframes_t time, jack_midi_data_t byte); bool SendNonRTBytes(jack_nframes_t boundary_frame); protected: /** * Override this method to specify what happens when the write queue * says that a 1-byte event is too large for its buffer. Basically, * this should never happen. */ virtual void HandleWriteQueueBug(jack_nframes_t time, jack_midi_data_t byte); public: using JackMidiWriteQueue::EnqueueEvent; /** * Called to create a new raw write queue. The `send_queue` argument * is the queue to write raw bytes to. The optional `max_rt_messages` * argument specifies the number of messages that can be enqueued in * the internal realtime queue. The optional `max_non_rt_messages` * argument specifies the number of messages that can be enqueued in * the internal non-realtime queue. The optional `non_rt_size` * argument specifies the total number of MIDI bytes that can be put in * the non-realtime queue. */ JackMidiRawOutputWriteQueue(JackMidiSendQueue *send_queue, size_t non_rt_size=4096, size_t max_non_rt_messages=1024, size_t max_rt_messages=128); ~JackMidiRawOutputWriteQueue(); EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); /** * The `Process()` method should be called each time the * `EnqueueEvent()` method returns 'OK'. The `Process()` method will * return the next frame at which an event should be sent. The return * value from `Process()` depends upon the result of writing bytes to * the write queue: * * -If the return value is '0', then all events that have been enqueued * in this queue have been sent successfully to the write queue. Don't * call `Process()` again until another event has been enqueued. * * -If the return value is an earlier frame or the current frame, it * means that the write queue returned 'BUFFER_FULL', 'ERROR', or * 'EVENT_EARLY' when this queue attempted to send the next byte, and * that the byte should have already been sent, or is scheduled to be * sent *now*. `Process()` should be called again when the write queue * can enqueue events again successfully. How to determine when this * will happen is left up to the caller. * * -If the return value is in the future, then `Process()` should be * called again at that time, or after another event is enqueued. */ jack_nframes_t Process(jack_nframes_t boundary_frame=0); }; } #endif 1.9.12~dfsg/common/JackEngineProfiling.h0000644000000000000000000000621213214314510016652 0ustar rootroot/* Copyright (C) 2008 Grame & RTL This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackEngineProfiling__ #define __JackEngineProfiling__ #include "types.h" #include "JackTypes.h" #include "JackConstants.h" #include "JackShmMem.h" namespace Jack { #define TIME_POINTS 100000 #define FAILURE_TIME_POINTS 10000 #define FAILURE_WINDOW 10 #define MEASURED_CLIENTS 32 /*! \brief Timing stucture for a client. */ PRE_PACKED_STRUCTURE struct JackTimingMeasureClient { int fRefNum; jack_time_t fSignaledAt; jack_time_t fAwakeAt; jack_time_t fFinishedAt; jack_client_state_t fStatus; JackTimingMeasureClient() :fRefNum(-1), fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus((jack_client_state_t)0) {} } POST_PACKED_STRUCTURE; /*! \brief Timing interval in the global table for a given client */ PRE_PACKED_STRUCTURE struct JackTimingClientInterval { int fRefNum; char fName[JACK_CLIENT_NAME_SIZE + 1]; int fBeginInterval; int fEndInterval; JackTimingClientInterval() :fRefNum(-1), fBeginInterval(-1), fEndInterval(-1) {} } POST_PACKED_STRUCTURE; /*! \brief Timing stucture for a table of clients. */ PRE_PACKED_STRUCTURE struct JackTimingMeasure { unsigned int fAudioCycle; jack_time_t fPeriodUsecs; jack_time_t fCurCycleBegin; jack_time_t fPrevCycleEnd; JackTimingMeasureClient fClientTable[CLIENT_NUM]; JackTimingMeasure() :fAudioCycle(0), fPeriodUsecs(0), fCurCycleBegin(0), fPrevCycleEnd(0) {} } POST_PACKED_STRUCTURE; /*! \brief Client timing monitoring. */ class JackClientInterface; class JackGraphManager; PRE_PACKED_STRUCTURE class SERVER_EXPORT JackEngineProfiling { private: JackTimingMeasure fProfileTable[TIME_POINTS]; JackTimingClientInterval fIntervalTable[MEASURED_CLIENTS]; unsigned int fAudioCycle; unsigned int fMeasuredClient; bool CheckClient(const char* name, int cur_point); public: JackEngineProfiling(); ~JackEngineProfiling(); void Profile(JackClientInterface** table, JackGraphManager* manager, jack_time_t period_usecs, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); JackTimingMeasure* GetCurMeasure(); } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackMidiBufferReadQueue.h0000644000000000000000000000300113214314510017401 0ustar rootroot/* Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMidiBufferReadQueue__ #define __JackMidiBufferReadQueue__ #include "JackMidiReadQueue.h" namespace Jack { /** * Wrapper class to present a JackMidiBuffer in a read queue interface. */ class SERVER_EXPORT JackMidiBufferReadQueue: public JackMidiReadQueue { private: JackMidiBuffer *buffer; jack_nframes_t event_count; jack_nframes_t index; jack_nframes_t last_frame_time; jack_midi_event_t midi_event; public: JackMidiBufferReadQueue(); jack_midi_event_t * DequeueEvent(); /** * This method must be called each period to reset the MIDI buffer for * processing. */ void ResetMidiBuffer(JackMidiBuffer *buffer); }; } #endif 1.9.12~dfsg/common/varargs.h0000644000000000000000000000465313214314510014456 0ustar rootroot/* * Copyright (C) 2004 Jack O'Quin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __jack_varargs_h__ #define __jack_varargs_h__ #include #include #include #include "types.h" #ifdef __cplusplus extern "C" { #endif /* variable argument structure */ typedef struct { char *server_name; /* server name */ char *load_name; /* load module name */ char *load_init; /* initialization string */ int session_id; /* requested session_id */ } jack_varargs_t; static const char* jack_default_server_name (void) { const char *server_name; if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) server_name = "default"; return server_name; } static inline void jack_varargs_init (jack_varargs_t *va) { memset (va, 0, sizeof(jack_varargs_t)); va->server_name = (char*)jack_default_server_name(); va->session_id = -1; } static inline void jack_varargs_parse (jack_options_t options, va_list ap, jack_varargs_t *va) { // initialize default settings jack_varargs_init (va); if ((options & JackServerName)) { char *sn = va_arg(ap, char *); if (sn) va->server_name = sn; } if ((options & JackLoadName)) va->load_name = va_arg(ap, char *); if ((options & JackLoadInit)) va->load_init = va_arg(ap, char *); if ((options & JackSessionID)) { char *sid = va_arg(ap, char *); if (sid) va->session_id = atoi( sid ); } } #ifdef __cplusplus } #endif #endif /* __jack_varargs_h__ */ 1.9.12~dfsg/common/JackEngineControl.cpp0000644000000000000000000000753313214314510016703 0ustar rootroot/* Copyright (C) 2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackClientInterface.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackClientControl.h" #include #include namespace Jack { static inline jack_time_t JACK_MAX(jack_time_t a, jack_time_t b) { return (a < b) ? b : a; } void JackEngineControl::CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { fPrevCycleTime = fCurCycleTime; fCurCycleTime = cur_cycle_begin; jack_time_t last_cycle_end = prev_cycle_end; // In Asynchronous mode, last cycle end is the max of client end dates if (!fSyncMode) { for (int i = fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; JackClientTiming* timing = manager->GetClientTiming(i); if (client && client->GetClientControl()->fActive && timing->fStatus == Finished) { last_cycle_end = JACK_MAX(last_cycle_end, timing->fFinishedAt); } } } // Store the execution time for later averaging if (last_cycle_end > 0) { fRollingClientUsecs[fRollingClientUsecsIndex++] = last_cycle_end - fPrevCycleTime; } if (fRollingClientUsecsIndex >= JACK_ENGINE_ROLLING_COUNT) { fRollingClientUsecsIndex = 0; } // Each time we have a full set of iterations, recompute the current // usage from the latest JACK_ENGINE_ROLLING_COUNT client entries. if (fRollingClientUsecsCnt && (fRollingClientUsecsIndex == 0)) { jack_time_t avg_usecs = 0; jack_time_t max_usecs = 0; for (int i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) { avg_usecs += fRollingClientUsecs[i]; // This is really a running total to be averaged later max_usecs = JACK_MAX(fRollingClientUsecs[i], max_usecs); } fMaxUsecs = JACK_MAX(fMaxUsecs, max_usecs); if (max_usecs < ((fPeriodUsecs * 95) / 100)) { // Average the values from our JACK_ENGINE_ROLLING_COUNT array fSpareUsecs = (jack_time_t)(fPeriodUsecs - (avg_usecs / JACK_ENGINE_ROLLING_COUNT)); } else { // Use the 'worst case' value (or zero if we exceeded 'fPeriodUsecs') fSpareUsecs = jack_time_t((max_usecs < fPeriodUsecs) ? fPeriodUsecs - max_usecs : 0); } fCPULoad = ((1.f - (float(fSpareUsecs) / float(fPeriodUsecs))) * 50.f + (fCPULoad * 0.5f)); } fRollingClientUsecsCnt++; } void JackEngineControl::ResetRollingUsecs() { memset(fRollingClientUsecs, 0, sizeof(fRollingClientUsecs)); fRollingClientUsecsIndex = 0; fRollingClientUsecsCnt = 0; fSpareUsecs = 0; fRollingInterval = int(floor((JACK_ENGINE_ROLLING_INTERVAL * 1000.f) / fPeriodUsecs)); } void JackEngineControl::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) { ResetFrameTime(callback_usecs); fXrunDelayedUsecs = delayed_usecs; if (delayed_usecs > fMaxDelayedUsecs) { fMaxDelayedUsecs = delayed_usecs; } } } // end of namespace 1.9.12~dfsg/common/JackThreadedDriver.cpp0000644000000000000000000001453313214314510017027 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackThreadedDriver.h" #include "JackError.h" #include "JackTools.h" #include "JackGlobals.h" #include "JackEngineControl.h" namespace Jack { JackThreadedDriver::JackThreadedDriver(JackDriver* driver):fThread(this),fDriver(driver) {} JackThreadedDriver::~JackThreadedDriver() { delete fDriver; } int JackThreadedDriver::Open() { return fDriver->Open(); } int JackThreadedDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { return fDriver->Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } int JackThreadedDriver::Close() { return fDriver->Close(); } int JackThreadedDriver::Process() { return fDriver->Process(); } int JackThreadedDriver::Attach() { return fDriver->Attach(); } int JackThreadedDriver::Detach() { return fDriver->Detach(); } int JackThreadedDriver::Read() { return fDriver->Read(); } int JackThreadedDriver::Write() { return fDriver->Write(); } bool JackThreadedDriver::IsFixedBufferSize() { return fDriver->IsFixedBufferSize(); } int JackThreadedDriver::SetBufferSize(jack_nframes_t buffer_size) { return fDriver->SetBufferSize(buffer_size); } int JackThreadedDriver::SetSampleRate(jack_nframes_t sample_rate) { return fDriver->SetSampleRate(sample_rate); } void JackThreadedDriver::SetMaster(bool onoff) { fDriver->SetMaster(onoff); } bool JackThreadedDriver::GetMaster() { return fDriver->GetMaster(); } void JackThreadedDriver::AddSlave(JackDriverInterface* slave) { fDriver->AddSlave(slave); } void JackThreadedDriver::RemoveSlave(JackDriverInterface* slave) { fDriver->RemoveSlave(slave); } int JackThreadedDriver::ProcessReadSlaves() { return fDriver->ProcessReadSlaves(); } int JackThreadedDriver::ProcessWriteSlaves() { return fDriver->ProcessWriteSlaves(); } int JackThreadedDriver::ProcessRead() { return fDriver->ProcessRead(); } int JackThreadedDriver::ProcessWrite() { return fDriver->ProcessWrite(); } int JackThreadedDriver::ProcessReadSync() { return fDriver->ProcessReadSync(); } int JackThreadedDriver::ProcessWriteSync() { return fDriver->ProcessWriteSync(); } int JackThreadedDriver::ProcessReadAsync() { return fDriver->ProcessReadAsync(); } int JackThreadedDriver::ProcessWriteAsync() { return fDriver->ProcessWriteAsync(); } std::list JackThreadedDriver::GetSlaves() { return fDriver->GetSlaves(); } int JackThreadedDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { return fDriver->ClientNotify(refnum, name, notify, sync, message, value1, value2); } JackClientControl* JackThreadedDriver::GetClientControl() const { return fDriver->GetClientControl(); } bool JackThreadedDriver::IsRealTime() const { return fDriver->IsRealTime(); } bool JackThreadedDriver::IsRunning() const { return fDriver->IsRunning(); } int JackThreadedDriver::Start() { jack_log("JackThreadedDriver::Start"); if (fDriver->Start() < 0) { jack_error("Cannot start driver"); return -1; } if (fThread.StartSync() < 0) { jack_error("Cannot start thread"); return -1; } return 0; } int JackThreadedDriver::Stop() { jack_log("JackThreadedDriver::Stop"); switch (fThread.GetStatus()) { // Kill the thread in Init phase case JackThread::kStarting: case JackThread::kIniting: if (fThread.Kill() < 0) { jack_error("Cannot kill thread"); } break; // Stop when the thread cycle is finished case JackThread::kRunning: if (fThread.Stop() < 0) { jack_error("Cannot stop thread"); } break; default: break; } if (fDriver->Stop() < 0) { jack_error("Cannot stop driver"); return -1; } return 0; } bool JackThreadedDriver::Execute() { return (Process() == 0); } bool JackThreadedDriver::Init() { if (fDriver->Initialize()) { SetRealTime(); return true; } else { return false; } } void JackThreadedDriver::SetRealTime() { if (fDriver->IsRealTime()) { jack_log("JackThreadedDriver::Init real-time"); // Will do "something" on OSX only... GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; GetEngineControl()->fComputation = JackTools::ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } } else { jack_log("JackThreadedDriver::Init non-realtime"); } } } // end of namespace 1.9.12~dfsg/common/JackClient.cpp0000644000000000000000000011710213214314510015345 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackSystemDeps.h" #include "JackGraphManager.h" #include "JackClientControl.h" #include "JackEngineControl.h" #include "JackGlobals.h" #include "JackChannel.h" #include "JackTransportEngine.h" #include "driver_interface.h" #include "JackLibGlobals.h" #include #include #include using namespace std; namespace Jack { #define IsRealTime() ((fProcess != NULL) | (fThreadFun != NULL) | (fSync != NULL) | (fTimebase != NULL)) JackClient::JackClient(JackSynchro* table):fThread(this) { fSynchroTable = table; fProcess = NULL; fGraphOrder = NULL; fXrun = NULL; fShutdown = NULL; fInfoShutdown = NULL; fInit = NULL; fBufferSize = NULL; fClientRegistration = NULL; fFreewheel = NULL; fPortRegistration = NULL; fPortConnect = NULL; fPortRename = NULL; fTimebase = NULL; fSync = NULL; fThreadFun = NULL; fSession = NULL; fLatency = NULL; fProcessArg = NULL; fGraphOrderArg = NULL; fXrunArg = NULL; fShutdownArg = NULL; fInfoShutdownArg = NULL; fInitArg = NULL; fBufferSizeArg = NULL; fFreewheelArg = NULL; fClientRegistrationArg = NULL; fPortRegistrationArg = NULL; fPortConnectArg = NULL; fPortRenameArg = NULL; fSyncArg = NULL; fTimebaseArg = NULL; fThreadFunArg = NULL; fSessionArg = NULL; fLatencyArg = NULL; fSessionReply = kPendingSessionReply; } JackClient::~JackClient() {} void JackClient::ShutDown(jack_status_t code, const char* message) { jack_log("JackClient::ShutDown"); // If "fInfoShutdown" callback, then call it if (fInfoShutdown) { fInfoShutdown(code, message, fInfoShutdownArg); fInfoShutdown = NULL; // Otherwise possibly call the normal "fShutdown" } else if (fShutdown) { fShutdown(fShutdownArg); fShutdown = NULL; } } int JackClient::Close() { jack_log("JackClient::Close ref = %ld", GetClientControl()->fRefNum); int result = 0; Deactivate(); // Channels is stopped first to avoid receiving notifications while closing fChannel->Stop(); // Then close client fChannel->ClientClose(GetClientControl()->fRefNum, &result); fChannel->Close(); assert(JackGlobals::fSynchroMutex); JackGlobals::fSynchroMutex->Lock(); fSynchroTable[GetClientControl()->fRefNum].Disconnect(); JackGlobals::fSynchroMutex->Unlock(); JackGlobals::fClientTable[GetClientControl()->fRefNum] = NULL; return result; } bool JackClient::IsActive() { return (GetClientControl()) ? GetClientControl()->fActive : false; } jack_native_thread_t JackClient::GetThreadID() { return fThread.GetThreadID(); } /*! In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel. */ void JackClient::SetupDriverSync(bool freewheel) { if (!freewheel && !GetEngineControl()->fSyncMode) { jack_log("JackClient::SetupDriverSync driver sem in flush mode"); for (int i = 0; i < GetEngineControl()->fDriverNum; i++) { fSynchroTable[i].SetFlush(true); } } else { jack_log("JackClient::SetupDriverSync driver sem in normal mode"); for (int i = 0; i < GetEngineControl()->fDriverNum; i++) { fSynchroTable[i].SetFlush(false); } } } /*! \brief Notification received from the server. */ int JackClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { return 0; } int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int res = 0; jack_log("JackClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify); // Done all time: redirected on subclass implementation JackLibClient and JackInternalClient switch (notify) { case kAddClient: res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2); break; case kRemoveClient: res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2); break; case kActivateClient: jack_log("JackClient::kActivateClient name = %s ref = %ld ", name, refnum); InitAux(); break; } /* The current semantic is that notifications can only be received when the client has been activated, although is this implementation, one could imagine calling notifications as soon as the client has be opened. */ if (IsActive()) { switch (notify) { case kAddClient: jack_log("JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name); if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself fClientRegistration(name, 1, fClientRegistrationArg); } break; case kRemoveClient: jack_log("JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName, name); if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself fClientRegistration(name, 0, fClientRegistrationArg); } break; case kBufferSizeCallback: jack_log("JackClient::kBufferSizeCallback buffer_size = %ld", value1); if (fBufferSize) { res = fBufferSize(value1, fBufferSizeArg); } break; case kSampleRateCallback: jack_log("JackClient::kSampleRateCallback sample_rate = %ld", value1); if (fSampleRate) { res = fSampleRate(value1, fSampleRateArg); } break; case kGraphOrderCallback: jack_log("JackClient::kGraphOrderCallback"); if (fGraphOrder) { res = fGraphOrder(fGraphOrderArg); } break; case kStartFreewheelCallback: jack_log("JackClient::kStartFreewheel"); SetupDriverSync(true); // Drop RT only when the RT thread is actually running if (fThread.GetStatus() == JackThread::kRunning) { fThread.DropRealTime(); } if (fFreewheel) { fFreewheel(1, fFreewheelArg); } break; case kStopFreewheelCallback: jack_log("JackClient::kStopFreewheel"); SetupDriverSync(false); if (fFreewheel) { fFreewheel(0, fFreewheelArg); } // Acquire RT only when the RT thread is actually running if (GetEngineControl()->fRealTime && fThread.GetStatus() == JackThread::kRunning) { if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) { jack_error("JackClient::AcquireRealTime error"); } } break; case kPortRegistrationOnCallback: jack_log("JackClient::kPortRegistrationOn port_index = %ld", value1); if (fPortRegistration) { fPortRegistration(value1, 1, fPortRegistrationArg); } break; case kPortRegistrationOffCallback: jack_log("JackClient::kPortRegistrationOff port_index = %ld ", value1); if (fPortRegistration) { fPortRegistration(value1, 0, fPortRegistrationArg); } break; case kPortConnectCallback: jack_log("JackClient::kPortConnectCallback src = %ld dst = %ld", value1, value2); if (fPortConnect) { fPortConnect(value1, value2, 1, fPortConnectArg); } break; case kPortDisconnectCallback: jack_log("JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1, value2); if (fPortConnect) { fPortConnect(value1, value2, 0, fPortConnectArg); } break; case kPortRenameCallback: jack_log("JackClient::kPortRenameCallback port = %ld", value1); if (fPortRename) { fPortRename(value1, message, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg); } break; case kXRunCallback: jack_log("JackClient::kXRunCallback"); if (fXrun) { res = fXrun(fXrunArg); } break; case kShutDownCallback: jack_log("JackClient::kShutDownCallback"); ShutDown(jack_status_t(value1), message); break; case kSessionCallback: jack_log("JackClient::kSessionCallback"); if (fSession) { jack_session_event_t* event = (jack_session_event_t*)malloc( sizeof(jack_session_event_t)); char uuid_buf[JACK_UUID_SIZE]; event->type = (jack_session_event_type_t)value1; event->session_dir = strdup(message); event->command_line = NULL; event->flags = (jack_session_flags_t)0; snprintf(uuid_buf, sizeof(uuid_buf), "%d", GetClientControl()->fSessionID); event->client_uuid = strdup(uuid_buf); fSessionReply = kPendingSessionReply; // Session callback may change fSessionReply by directly using jack_session_reply fSession(event, fSessionArg); res = fSessionReply; } break; case kLatencyCallback: res = HandleLatencyCallback(value1); break; } } return res; } int JackClient::HandleLatencyCallback(int status) { jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; jack_latency_range_t latency = { UINT32_MAX, 0 }; /* first setup all latency values of the ports. * this is based on the connections of the ports. */ list::iterator it; for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) { GetGraphManager()->RecalculateLatency(*it, mode); } if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) { GetGraphManager()->RecalculateLatency(*it, mode); } } if (!fLatency) { /* * default action is to assume all ports depend on each other. * then always take the maximum latency. */ if (mode == JackPlaybackLatency) { /* iterate over all OutputPorts, to find maximum playback latency */ for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if (port->GetFlags() & JackPortIsOutput) { jack_latency_range_t other_latency; port->GetLatencyRange(mode, &other_latency); if (other_latency.max > latency.max) { latency.max = other_latency.max; } if (other_latency.min < latency.min) { latency.min = other_latency.min; } } } if (latency.min == UINT32_MAX) { latency.min = 0; } /* now set the found latency on all input ports */ for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if (port->GetFlags() & JackPortIsInput) { port->SetLatencyRange(mode, &latency); } } } if (mode == JackCaptureLatency) { /* iterate over all InputPorts, to find maximum playback latency */ for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if (port->GetFlags() & JackPortIsInput) { jack_latency_range_t other_latency; port->GetLatencyRange(mode, &other_latency); if (other_latency.max > latency.max) { latency.max = other_latency.max; } if (other_latency.min < latency.min) { latency.min = other_latency.min; } } } if (latency.min == UINT32_MAX) { latency.min = 0; } /* now set the found latency on all output ports */ for (it = fPortList.begin(); it != fPortList.end(); it++) { JackPort* port = GetGraphManager()->GetPort(*it); if (port->GetFlags() & JackPortIsOutput) { port->SetLatencyRange(mode, &latency); } } } return 0; } /* we have a latency callback setup by the client, * lets use it... */ fLatency(mode, fLatencyArg); return 0; } /*! \brief We need to start thread before activating in the server, otherwise the FW driver connected to the client may not be activated. */ int JackClient::Activate() { jack_log("JackClient::Activate"); if (IsActive()) { return 0; } // RT thread is started only when needed... if (IsRealTime()) { if (StartThread() < 0) { return -1; } } /* Insertion of client in the graph will cause a kGraphOrderCallback notification to be delivered by the server, the client wants to receive it. */ GetClientControl()->fActive = true; // Transport related callback become "active" GetClientControl()->fTransportSync = true; GetClientControl()->fTransportTimebase = true; int result = -1; GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime(); fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result); return result; } /*! \brief Need to stop thread after deactivating in the server. */ int JackClient::Deactivate() { jack_log("JackClient::Deactivate"); if (!IsActive()) { return 0; } GetClientControl()->fActive = false; // Transport related callback become "unactive" GetClientControl()->fTransportSync = false; GetClientControl()->fTransportTimebase = false; // We need to wait for the new engine cycle before stopping the RT thread, but this is done by ClientDeactivate int result = -1; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); jack_log("JackClient::Deactivate res = %ld", result); // RT thread is stopped only when needed... if (IsRealTime()) { fThread.Kill(); } return result; } //---------------------- // RT thread management //---------------------- void JackClient::InitAux() { if (fInit) { jack_log("JackClient::Init calling client thread init callback"); fInit(fInitArg); } } /*! \brief Called once when the thread starts. */ bool JackClient::Init() { /* Execute buffer_size callback. Since StartThread uses fThread.StartSync, we are sure that buffer_size callback is executed before StartThread returns (and then IsActive will be true). So no RT callback can be called at the same time. */ jack_log("JackClient::kBufferSizeCallback buffer_size = %ld", GetEngineControl()->fBufferSize); if (fBufferSize) { fBufferSize(GetEngineControl()->fBufferSize, fBufferSizeArg); } // Init callback InitAux(); // Setup context if (!jack_tls_set(JackGlobals::fRealTimeThread, this)) { jack_error("Failed to set thread realtime key"); } // Setup RT if (GetEngineControl()->fRealTime) { set_threaded_log_function(); SetupRealTime(); } return true; } void JackClient::SetupRealTime() { jack_log("JackClient::Init : period = %ld computation = %ld constraint = %ld", long(int64_t(GetEngineControl()->fPeriod) / 1000.0f), long(int64_t(GetEngineControl()->fComputation) / 1000.0f), long(int64_t(GetEngineControl()->fConstraint) / 1000.0f)); // Will do "something" on OSX only... fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) { jack_error("JackClient::AcquireSelfRealTime error"); } } int JackClient::StartThread() { if (fThread.StartSync() < 0) { jack_error("Start thread error"); return -1; } return 0; } /*! \brief RT thread. */ bool JackClient::Execute() { // Execute a dummy cycle to be sure thread has the correct properties DummyCycle(); if (fThreadFun) { fThreadFun(fThreadFunArg); } else { ExecuteThread(); } return false; } void JackClient::DummyCycle() { WaitSync(); SignalSync(); } inline void JackClient::ExecuteThread() { while (true) { CycleWaitAux(); CycleSignalAux(CallProcessCallback()); } } inline jack_nframes_t JackClient::CycleWaitAux() { if (!WaitSync()) { Error(); // Terminates the thread } CallSyncCallbackAux(); return GetEngineControl()->fBufferSize; } inline void JackClient::CycleSignalAux(int status) { if (status == 0) { CallTimebaseCallbackAux(); } SignalSync(); if (status != 0) { End(); // Terminates the thread } } jack_nframes_t JackClient::CycleWait() { return CycleWaitAux(); } void JackClient::CycleSignal(int status) { CycleSignalAux(status); } inline int JackClient::CallProcessCallback() { return (fProcess != NULL) ? fProcess(GetEngineControl()->fBufferSize, fProcessArg) : 0; } inline bool JackClient::WaitSync() { // Suspend itself: wait on the input synchro if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable, 0x7FFFFFFF) < 0) { jack_error("SuspendRefNum error"); return false; } else { return true; } } inline void JackClient::SignalSync() { // Resume: signal output clients connected to the running client if (GetGraphManager()->ResumeRefNum(GetClientControl(), fSynchroTable) < 0) { jack_error("ResumeRefNum error"); } } inline void JackClient::End() { jack_log("JackClient::Execute end name = %s", GetClientControl()->fName); // Hum... not sure about this, the following "close" code is called in the RT thread... int result; fThread.DropSelfRealTime(); GetClientControl()->fActive = false; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); fThread.Terminate(); } inline void JackClient::Error() { jack_error("JackClient::Execute error name = %s", GetClientControl()->fName); // Hum... not sure about this, the following "close" code is called in the RT thread... int result; fThread.DropSelfRealTime(); GetClientControl()->fActive = false; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE); fThread.Terminate(); } //----------------- // Port management //----------------- int JackClient::PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size) { // Check if port name is empty string port_short_name_str = string(port_name); if (port_short_name_str.size() == 0) { jack_error("port_name is empty"); return 0; // Means failure here... } // Check port name length string port_full_name_str = string(GetClientControl()->fName) + string(":") + port_short_name_str; if (port_full_name_str.size() >= REAL_JACK_PORT_NAME_SIZE) { jack_error("\"%s:%s\" is too long to be used as a JACK port name.\n" "Please use %lu characters or less", GetClientControl()->fName, port_name, JACK_PORT_NAME_SIZE - 1); return 0; // Means failure here... } int result = -1; jack_port_id_t port_index = NO_PORT; fChannel->PortRegister(GetClientControl()->fRefNum, port_full_name_str.c_str(), port_type, flags, buffer_size, &port_index, &result); if (result == 0) { jack_log("JackClient::PortRegister ref = %ld name = %s type = %s port_index = %ld", GetClientControl()->fRefNum, port_full_name_str.c_str(), port_type, port_index); fPortList.push_back(port_index); return port_index; } else { return 0; } } int JackClient::PortUnRegister(jack_port_id_t port_index) { jack_log("JackClient::PortUnRegister port_index = %ld", port_index); list::iterator it = find(fPortList.begin(), fPortList.end(), port_index); if (it != fPortList.end()) { fPortList.erase(it); int result = -1; fChannel->PortUnRegister(GetClientControl()->fRefNum, port_index, &result); return result; } else { jack_error("unregistering a port %ld that is not own by the client", port_index); return -1; } } int JackClient::PortConnect(const char* src, const char* dst) { jack_log("JackClient::Connect src = %s dst = %s", src, dst); if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) { jack_error("\"%s\" is too long to be used as a JACK port name.\n", src); return -1; } if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) { jack_error("\"%s\" is too long to be used as a JACK port name.\n", src); return -1; } int result = -1; fChannel->PortConnect(GetClientControl()->fRefNum, src, dst, &result); return result; } int JackClient::PortDisconnect(const char* src, const char* dst) { jack_log("JackClient::Disconnect src = %s dst = %s", src, dst); if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) { jack_error("\"%s\" is too long to be used as a JACK port name.\n", src); return -1; } if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) { jack_error("\"%s\" is too long to be used as a JACK port name.\n", src); return -1; } int result = -1; fChannel->PortDisconnect(GetClientControl()->fRefNum, src, dst, &result); return result; } int JackClient::PortDisconnect(jack_port_id_t src) { jack_log("JackClient::PortDisconnect src = %ld", src); int result = -1; fChannel->PortDisconnect(GetClientControl()->fRefNum, src, ALL_PORTS, &result); return result; } int JackClient::PortIsMine(jack_port_id_t port_index) { JackPort* port = GetGraphManager()->GetPort(port_index); return GetClientControl()->fRefNum == port->GetRefNum(); } int JackClient::PortRename(jack_port_id_t port_index, const char* name) { int result = -1; fChannel->PortRename(GetClientControl()->fRefNum, port_index, name, &result); return result; } //-------------------- // Context management //-------------------- int JackClient::SetBufferSize(jack_nframes_t buffer_size) { int result = -1; fChannel->SetBufferSize(buffer_size, &result); return result; } int JackClient::SetFreeWheel(int onoff) { int result = -1; fChannel->SetFreewheel(onoff, &result); return result; } int JackClient::ComputeTotalLatencies() { int result = -1; fChannel->ComputeTotalLatencies(&result); return result; } //---------------------- // Transport management //---------------------- inline int JackClient::ActivateAux() { // If activated without RT thread... if (IsActive() && fThread.GetStatus() != JackThread::kRunning) { jack_log("JackClient::ActivateAux"); // RT thread is started if (StartThread() < 0) { return -1; } int result = -1; GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime(); fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result); return result; } else { return 0; } } int JackClient::ReleaseTimebase() { int result = -1; fChannel->ReleaseTimebase(GetClientControl()->fRefNum, &result); if (result == 0) { GetClientControl()->fTransportTimebase = false; fTimebase = NULL; fTimebaseArg = NULL; } return result; } /* Call the server if the client is active, otherwise keeps the arguments */ int JackClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg) { GetClientControl()->fTransportSync = (fSync != NULL); fSyncArg = arg; fSync = sync_callback; return ActivateAux(); } int JackClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg) { int result = -1; fChannel->SetTimebaseCallback(GetClientControl()->fRefNum, conditional, &result); if (result == 0) { GetClientControl()->fTransportTimebase = true; fTimebase = timebase_callback; fTimebaseArg = arg; return ActivateAux(); } else { fTimebase = NULL; fTimebaseArg = NULL; return result; } } int JackClient::SetSyncTimeout(jack_time_t timeout) { GetEngineControl()->fTransport.SetSyncTimeout(timeout); return 0; } // Must be RT safe void JackClient::TransportLocate(jack_nframes_t frame) { jack_position_t pos; pos.frame = frame; pos.valid = (jack_position_bits_t)0; jack_log("JackClient::TransportLocate pos = %ld", pos.frame); GetEngineControl()->fTransport.RequestNewPos(&pos); } int JackClient::TransportReposition(const jack_position_t* pos) { jack_position_t tmp = *pos; jack_log("JackClient::TransportReposition pos = %ld", pos->frame); if (tmp.valid & ~JACK_POSITION_MASK) { return EINVAL; } else { GetEngineControl()->fTransport.RequestNewPos(&tmp); return 0; } } jack_transport_state_t JackClient::TransportQuery(jack_position_t* pos) { return GetEngineControl()->fTransport.Query(pos); } jack_nframes_t JackClient::GetCurrentTransportFrame() { return GetEngineControl()->fTransport.GetCurrentFrame(); } // Must be RT safe: directly write in the transport shared mem void JackClient::TransportStart() { GetEngineControl()->fTransport.SetCommand(TransportCommandStart); } // Must be RT safe: directly write in the transport shared mem void JackClient::TransportStop() { GetEngineControl()->fTransport.SetCommand(TransportCommandStop); } // Never called concurently with the server // TODO check concurrency with SetSyncCallback void JackClient::CallSyncCallback() { CallSyncCallbackAux(); } inline void JackClient::CallSyncCallbackAux() { if (GetClientControl()->fTransportSync) { JackTransportEngine& transport = GetEngineControl()->fTransport; jack_position_t* cur_pos = transport.ReadCurrentState(); jack_transport_state_t transport_state = transport.GetState(); if (fSync != NULL) { if (fSync(transport_state, cur_pos, fSyncArg)) { GetClientControl()->fTransportState = JackTransportRolling; GetClientControl()->fTransportSync = false; } } else { GetClientControl()->fTransportState = JackTransportRolling; GetClientControl()->fTransportSync = false; } } } void JackClient::CallTimebaseCallback() { CallTimebaseCallbackAux(); } inline void JackClient::CallTimebaseCallbackAux() { JackTransportEngine& transport = GetEngineControl()->fTransport; int master; bool unused; transport.GetTimebaseMaster(master, unused); if (GetClientControl()->fRefNum == master && fTimebase) { // Client *is* timebase... jack_transport_state_t transport_state = transport.GetState(); jack_position_t* cur_pos = transport.WriteNextStateStart(1); if (GetClientControl()->fTransportTimebase) { fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos, true, fTimebaseArg); GetClientControl()->fTransportTimebase = false; // Callback is called only once with "new_pos" = true } else if (transport_state == JackTransportRolling) { fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos, false, fTimebaseArg); } transport.WriteNextStateStop(1); } } //--------------------- // Callback management //--------------------- void JackClient::OnShutdown(JackShutdownCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); } else { // Shutdown callback will either be an old API version or the new version (with info) GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL); fShutdownArg = arg; fShutdown = callback; } } void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); } else { // Shutdown callback will either be an old API version or the new version (with info) GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL); fInfoShutdownArg = arg; fInfoShutdown = callback; } } int JackClient::SetProcessCallback(JackProcessCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else if (fThreadFun) { jack_error ("A thread callback has already been setup, both models cannot be used at the same time!"); return -1; } else { fProcessArg = arg; fProcess = callback; return 0; } } int JackClient::SetXRunCallback(JackXRunCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kXRunCallback] = (callback != NULL); fXrunArg = arg; fXrun = callback; return 0; } } int JackClient::SetInitCallback(JackThreadInitCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { fInitArg = arg; fInit = callback; /* make sure that the message buffer thread is initialized too */ return JackMessageBuffer::fInstance->SetInitCallback(callback, arg); } } int JackClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kGraphOrderCallback] = (callback != NULL); fGraphOrder = callback; fGraphOrderArg = arg; return 0; } } int JackClient::SetBufferSizeCallback(JackBufferSizeCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kBufferSizeCallback] = (callback != NULL); fBufferSizeArg = arg; fBufferSize = callback; return 0; } } int JackClient::SetSampleRateCallback(JackSampleRateCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL); fSampleRateArg = arg; fSampleRate = callback; // Now invoke it if (callback) { callback(GetEngineControl()->fSampleRate, arg); } return 0; } } int JackClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { // kAddClient and kRemoveClient notifications must be delivered by the server in any case fClientRegistrationArg = arg; fClientRegistration = callback; return 0; } } int JackClient::SetFreewheelCallback(JackFreewheelCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kStartFreewheelCallback] = (callback != NULL); GetClientControl()->fCallback[kStopFreewheelCallback] = (callback != NULL); fFreewheelArg = arg; fFreewheel = callback; return 0; } } int JackClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kPortRegistrationOnCallback] = (callback != NULL); GetClientControl()->fCallback[kPortRegistrationOffCallback] = (callback != NULL); fPortRegistrationArg = arg; fPortRegistration = callback; return 0; } } int JackClient::SetPortConnectCallback(JackPortConnectCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kPortConnectCallback] = (callback != NULL); GetClientControl()->fCallback[kPortDisconnectCallback] = (callback != NULL); fPortConnectArg = arg; fPortConnect = callback; return 0; } } int JackClient::SetPortRenameCallback(JackPortRenameCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kPortRenameCallback] = (callback != NULL); fPortRenameArg = arg; fPortRename = callback; return 0; } } int JackClient::SetProcessThread(JackThreadCallback fun, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else if (fProcess) { jack_error("A process callback has already been setup, both models cannot be used at the same time!"); return -1; } else { fThreadFun = fun; fThreadFunArg = arg; return 0; } } int JackClient::SetSessionCallback(JackSessionCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { GetClientControl()->fCallback[kSessionCallback] = (callback != NULL); fSessionArg = arg; fSession = callback; return 0; } } int JackClient::SetLatencyCallback(JackLatencyCallback callback, void *arg) { if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; } else { // fCallback[kLatencyCallback] must always be 'true' fLatencyArg = arg; fLatency = callback; return 0; } } //------------------ // Internal clients //------------------ char* JackClient::GetInternalClientName(int ref) { char name_res[JACK_CLIENT_NAME_SIZE+1]; int result = -1; fChannel->GetInternalClientName(GetClientControl()->fRefNum, ref, name_res, &result); return (result < 0) ? NULL : strdup(name_res); } int JackClient::InternalClientHandle(const char* client_name, jack_status_t* status) { int int_ref, result = -1; fChannel->InternalClientHandle(GetClientControl()->fRefNum, client_name, (int*)status, &int_ref, &result); return int_ref; } int JackClient::InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va) { if (strlen(client_name) >= JACK_CLIENT_NAME_SIZE) { jack_error ("\"%s\" is too long for a JACK client name.\n" "Please use %lu characters or less.", client_name, JACK_CLIENT_NAME_SIZE); return 0; } if (va->load_name && (strlen(va->load_name) >= JACK_PATH_MAX)) { jack_error("\"%s\" is too long for a shared object name.\n" "Please use %lu characters or less.", va->load_name, JACK_PATH_MAX); int my_status1 = *status | (JackFailure | JackInvalidOption); *status = (jack_status_t)my_status1; return 0; } if (va->load_init && (strlen(va->load_init) >= JACK_LOAD_INIT_LIMIT)) { jack_error ("\"%s\" is too long for internal client init " "string.\nPlease use %lu characters or less.", va->load_init, JACK_LOAD_INIT_LIMIT); int my_status1 = *status | (JackFailure | JackInvalidOption); *status = (jack_status_t)my_status1; return 0; } int int_ref, result = -1; fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (int*)status, &int_ref, -1, &result); return int_ref; } void JackClient::InternalClientUnload(int ref, jack_status_t* status) { int result = -1; fChannel->InternalClientUnload(GetClientControl()->fRefNum, ref, (int*)status, &result); } //------------------ // Session API //------------------ jack_session_command_t* JackClient::SessionNotify(const char* target, jack_session_event_type_t type, const char* path) { jack_session_command_t* res; fChannel->SessionNotify(GetClientControl()->fRefNum, target, type, path, &res); return res; } int JackClient::SessionReply(jack_session_event_t* ev) { if (ev->command_line) { strncpy(GetClientControl()->fSessionCommand, ev->command_line, sizeof(GetClientControl()->fSessionCommand)); } else { GetClientControl()->fSessionCommand[0] = '\0'; } GetClientControl()->fSessionFlags = ev->flags; jack_log("JackClient::SessionReply... we are here"); if (fChannel->IsChannelThread()) { jack_log("JackClient::SessionReply... in callback reply"); // OK, immediate reply... fSessionReply = kImmediateSessionReply; return 0; } jack_log("JackClient::SessionReply... out of cb"); int result = -1; fChannel->SessionReply(GetClientControl()->fRefNum, &result); return result; } char* JackClient::GetUUIDForClientName(const char* client_name) { char uuid_res[JACK_UUID_SIZE]; int result = -1; fChannel->GetUUIDForClientName(GetClientControl()->fRefNum, client_name, uuid_res, &result); return (result) ? NULL : strdup(uuid_res); } char* JackClient::GetClientNameByUUID(const char* uuid) { char name_res[JACK_CLIENT_NAME_SIZE + 1]; int result = -1; fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result); return (result) ? NULL : strdup(name_res); } int JackClient::ReserveClientName(const char* client_name, const char* uuid) { int result = -1; fChannel->ReserveClientName( GetClientControl()->fRefNum, client_name, uuid, &result); return result; } int JackClient::ClientHasSessionCallback(const char* client_name) { int result = -1; fChannel->ClientHasSessionCallback(client_name, &result); return result; } } // end of namespace 1.9.12~dfsg/common/JackNetTool.h0000644000000000000000000004277513214314510015175 0ustar rootroot/* Copyright (C) 2008-2011 Romain Moret at Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackMidiPort.h" #include "JackTools.h" #include "types.h" #include "transport.h" #ifndef WIN32 #include #endif #include using namespace std; #ifndef htonll #ifdef __BIG_ENDIAN__ #define htonll(x) (x) #define ntohll(x) (x) #else #define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl(x >> 32)) #define ntohll(x) ((((uint64_t)ntohl(x)) << 32) + ntohl(x >> 32)) #endif #endif #define NETWORK_PROTOCOL 8 #define NET_SYNCHING 0 #define SYNC_PACKET_ERROR -2 #define DATA_PACKET_ERROR -3 #define OPTIMIZED_PROTOCOL 1 #define UDP_HEADER_SIZE 64 // 40 bytes for IP header in IPV6, 20 in IPV4, 8 for UDP, so take 64 #define HEADER_SIZE (sizeof(packet_header_t)) #define PACKET_AVAILABLE_SIZE(params) ((params)->fMtu - UDP_HEADER_SIZE - HEADER_SIZE) namespace Jack { typedef struct _session_params session_params_t; typedef struct _packet_header packet_header_t; typedef struct _net_transport_data net_transport_data_t; typedef struct sockaddr socket_address_t; typedef struct in_addr address_t; typedef jack_default_audio_sample_t sample_t; enum JackNetEncoder { JackFloatEncoder = 0, JackIntEncoder = 1, JackCeltEncoder = 2, JackOpusEncoder = 3, }; //session params ****************************************************************************** /** \brief This structure containes master/slave connection parameters, it's used to setup the whole system We have : - some info like version, type and packet id - names - network parameters (hostnames and mtu) - nunber of audio and midi channels - sample rate and buffersize - number of audio frames in one network packet (depends on the channel number) - is the NetDriver in Sync or ASync mode ? - is the NetDriver linked with the master's transport Data encoding : headers (session_params and packet_header) are encoded using HTN kind of functions but float data are kept in LITTLE_ENDIAN format (to avoid 2 conversions in the more common LITTLE_ENDIAN <==> LITTLE_ENDIAN connection case). */ PRE_PACKED_STRUCTURE struct _session_params { char fPacketType[8]; //packet type ('param') uint32_t fProtocolVersion; //version int32_t fPacketID; //indicates the packet type char fName[JACK_CLIENT_NAME_SIZE]; //slave's name char fMasterNetName[JACK_SERVER_NAME_SIZE]; //master hostname (network) char fSlaveNetName[JACK_SERVER_NAME_SIZE]; //slave hostname (network) uint32_t fMtu; //connection mtu uint32_t fID; //slave's ID uint32_t fTransportSync; //is the transport synced ? int32_t fSendAudioChannels; //number of master->slave channels int32_t fReturnAudioChannels; //number of slave->master channels int32_t fSendMidiChannels; //number of master->slave midi channels int32_t fReturnMidiChannels; //number of slave->master midi channels uint32_t fSampleRate; //session sample rate uint32_t fPeriodSize; //period size uint32_t fSampleEncoder; //samples encoder uint32_t fKBps; //KB per second for CELT encoder uint32_t fSlaveSyncMode; //is the slave in sync mode ? uint32_t fNetworkLatency; //network latency } POST_PACKED_STRUCTURE; //net status ********************************************************************************** /** \Brief This enum groups network error by type */ enum _net_status { NET_SOCKET_ERROR = 0, NET_CONNECT_ERROR, NET_ERROR, NET_SEND_ERROR, NET_RECV_ERROR, NET_CONNECTED, NET_ROLLING }; typedef enum _net_status net_status_t; //sync packet type **************************************************************************** /** \Brief This enum indicates the type of a sync packet (used in the initialization phase) */ enum _sync_packet_type { INVALID = 0, //... SLAVE_AVAILABLE, //a slave is available SLAVE_SETUP, //slave configuration START_MASTER, //slave is ready, start master START_SLAVE, //master is ready, activate slave KILL_MASTER //master must stop }; typedef enum _sync_packet_type sync_packet_type_t; //packet header ******************************************************************************* /** \Brief This structure is a complete header A header indicates : - it is a header - the type of data the packet contains (sync, midi or audio) - the path of the packet (send -master->slave- or return -slave->master-) - the unique ID of the slave - the sample's bitdepth (unused for now) - the size of the midi data contains in the packet (indicates how much midi data will be sent) - the number of midi packet(s) : more than one is very unusual, it depends on the midi load - the ID of the current cycle (used to check missing packets) - the ID of the packet subcycle (for audio data) - a flag indicating this packet is the last of the cycle (for sync robustness, it's better to process this way) - a flag indicating if, in async mode, the previous graph was not finished or not - padding to fill 64 bytes */ PRE_PACKED_STRUCTURE struct _packet_header { char fPacketType[8]; //packet type ('headr') uint32_t fDataType; //'a' for audio, 'm' for midi and 's' for sync uint32_t fDataStream; //'s' for send, 'r' for return uint32_t fID; //unique ID of the slave uint32_t fNumPacket; //number of data packets of the cycle uint32_t fPacketSize; //packet size in bytes uint32_t fActivePorts; //number of active ports uint32_t fCycle; //process cycle counter uint32_t fSubCycle; //midi/audio subcycle counter int32_t fFrames; //process cycle size in frames (can be -1 to indicate entire buffer) uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') } POST_PACKED_STRUCTURE; //net timebase master /** \Brief This enum describes timebase master's type */ enum _net_timebase_master { NO_CHANGE = 0, RELEASE_TIMEBASEMASTER = 1, TIMEBASEMASTER = 2, CONDITIONAL_TIMEBASEMASTER = 3 }; typedef enum _net_timebase_master net_timebase_master_t; //transport data ****************************************************************************** /** \Brief This structure contains transport data to be sent over the network */ PRE_PACKED_STRUCTURE struct _net_transport_data { uint32_t fNewState; //is it a state change uint32_t fTimebaseMaster; //is there a new timebase master int32_t fState; //current cycle state jack_position_t fPosition; //current cycle position } POST_PACKED_STRUCTURE; //midi data *********************************************************************************** /** \Brief Midi buffer and operations class This class is a toolset to manipulate Midi buffers. A JackMidiBuffer has a fixed size, which is the same than an audio buffer size. An intermediate fixed size buffer allows to uninterleave midi data (from jack ports). But for a big majority of the process cycles, this buffer is filled less than 1%, Sending over a network 99% of useless data seems completely unappropriate. The idea is to count effective midi data, and then send the smallest packet we can. To do it, we use an intermediate buffer. We have two methods to convert data from jack ports to intermediate buffer, And two others to convert this intermediate buffer to a network buffer (header + payload data) */ class SERVER_EXPORT NetMidiBuffer { private: int fNPorts; size_t fMaxBufsize; int fMaxPcktSize; char* fBuffer; char* fNetBuffer; JackMidiBuffer** fPortBuffer; size_t fCycleBytesSize; // needed size in bytes ofr an entire cycle public: NetMidiBuffer(session_params_t* params, uint32_t nports, char* net_buffer); ~NetMidiBuffer(); void Reset(); // needed size in bytes for an entire cycle size_t GetCycleSize(); int GetNumPackets(int data_sizen, int max_size); void SetBuffer(int index, JackMidiBuffer* buffer); JackMidiBuffer* GetBuffer(int index); //utility void DisplayEvents(); //jack<->buffer int RenderFromJackPorts(); void RenderToJackPorts(); //network<->buffer void RenderFromNetwork(int sub_cycle, size_t copy_size); int RenderToNetwork(int sub_cycle, size_t total_size); }; // audio data ********************************************************************************* class SERVER_EXPORT NetAudioBuffer { protected: int fNPorts; int fLastSubCycle; int fNumPackets; char* fNetBuffer; sample_t** fPortBuffer; bool* fConnectedPorts; jack_nframes_t fPeriodSize; jack_nframes_t fSubPeriodSize; size_t fSubPeriodBytesSize; float fCycleDuration; // in sec size_t fCycleBytesSize; // needed size in bytes for an entire cycle int CheckPacket(int cycle, int sub_cycle); void NextCycle(); void Cleanup(); public: NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); virtual ~NetAudioBuffer(); bool GetConnected(int port_index) { return fConnectedPorts[port_index]; } void SetConnected(int port_index, bool state) { fConnectedPorts[port_index] = state; } // needed syze in bytes ofr an entire cycle virtual size_t GetCycleSize() = 0; // cycle duration in sec virtual float GetCycleDuration() = 0; virtual int GetNumPackets(int active_ports) = 0; virtual void SetBuffer(int index, sample_t* buffer); virtual sample_t* GetBuffer(int index); //jack<->buffer virtual int RenderFromJackPorts(int nframes); virtual void RenderToJackPorts(int nframes); //network<->buffer virtual int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num) = 0; virtual int RenderToNetwork(int sub_cycle, uint32_t port_num) = 0; virtual int ActivePortsToNetwork(char* net_buffer); virtual void ActivePortsFromNetwork(char* net_buffer, uint32_t port_num); }; class SERVER_EXPORT NetFloatAudioBuffer : public NetAudioBuffer { private: int fPacketSize; void UpdateParams(int active_ports); void RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle); void RenderToNetwork(char* net_buffer, int active_port, int sub_cycle); public: NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); virtual ~NetFloatAudioBuffer(); // needed size in bytes for an entire cycle size_t GetCycleSize(); // cycle duration in sec float GetCycleDuration(); int GetNumPackets(int active_ports); //jack<->buffer int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num); int RenderToNetwork(int sub_cycle, uint32_t port_num); }; #if HAVE_CELT #include class SERVER_EXPORT NetCeltAudioBuffer : public NetAudioBuffer { private: CELTMode** fCeltMode; CELTEncoder** fCeltEncoder; CELTDecoder** fCeltDecoder; int fCompressedSizeByte; unsigned char** fCompressedBuffer; size_t fLastSubPeriodBytesSize; void FreeCelt(); public: NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps); virtual ~NetCeltAudioBuffer(); // needed size in bytes for an entire cycle size_t GetCycleSize(); // cycle duration in sec float GetCycleDuration(); int GetNumPackets(int active_ports); //jack<->buffer int RenderFromJackPorts(int nframes); void RenderToJackPorts(int nframes); //network<->buffer int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num); int RenderToNetwork(int sub_cycle, uint32_t port_num); }; #endif #if HAVE_OPUS #include #include class SERVER_EXPORT NetOpusAudioBuffer : public NetAudioBuffer { private: OpusCustomMode** fOpusMode; OpusCustomEncoder** fOpusEncoder; OpusCustomDecoder** fOpusDecoder; int fCompressedMaxSizeByte; unsigned short* fCompressedSizesByte; size_t fLastSubPeriodBytesSize; unsigned char** fCompressedBuffer; void FreeOpus(); public: NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps); virtual ~NetOpusAudioBuffer(); // needed size in bytes for an entire cycle size_t GetCycleSize(); // cycle duration in sec float GetCycleDuration(); int GetNumPackets(int active_ports); //jack<->buffer int RenderFromJackPorts(int nframes); void RenderToJackPorts(int nframes); //network<->buffer int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num); int RenderToNetwork(int sub_cycle, uint32_t port_num); }; #endif class SERVER_EXPORT NetIntAudioBuffer : public NetAudioBuffer { private: int fCompressedSizeByte; size_t fLastSubPeriodBytesSize; short** fIntBuffer; public: NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); virtual ~NetIntAudioBuffer(); // needed size in bytes for an entire cycle size_t GetCycleSize(); // cycle duration in sec float GetCycleDuration(); int GetNumPackets(int active_ports); //jack<->buffer int RenderFromJackPorts(int nframes); void RenderToJackPorts(int nframes); //network<->buffer int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num); int RenderToNetwork(int sub_cycle, uint32_t port_num); }; //utility ************************************************************************************* //socket API management SERVER_EXPORT int SocketAPIInit(); SERVER_EXPORT int SocketAPIEnd(); //n<-->h functions SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params); SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params); SERVER_EXPORT void PacketHeaderHToN(packet_header_t* src_header, packet_header_t* dst_header); SERVER_EXPORT void PacketHeaderNToH(packet_header_t* src_header, packet_header_t* dst_header); SERVER_EXPORT void MidiBufferHToN(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer); SERVER_EXPORT void MidiBufferNToH(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer); SERVER_EXPORT void TransportDataHToN(net_transport_data_t* src_params, net_transport_data_t* dst_params); SERVER_EXPORT void TransportDataNToH(net_transport_data_t* src_params, net_transport_data_t* dst_params); //display session parameters SERVER_EXPORT void SessionParamsDisplay(session_params_t* params); //display packet header SERVER_EXPORT void PacketHeaderDisplay(packet_header_t* header); //get the packet type from a sesion parameters SERVER_EXPORT sync_packet_type_t GetPacketType(session_params_t* params); //set the packet type in a session parameters SERVER_EXPORT int SetPacketType(session_params_t* params, sync_packet_type_t packet_type); //transport utility SERVER_EXPORT const char* GetTransportState(int transport_state); SERVER_EXPORT void NetTransportDataDisplay(net_transport_data_t* data); } 1.9.12~dfsg/common/JackDebugClient.h0000644000000000000000000001335613214314510015767 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackDebugClient__ #define __JackDebugClient__ #define MAX_PORT_HISTORY 2048 #include "JackClient.h" #include #include namespace Jack { /*! \brief Follow a single port. */ typedef struct { jack_port_id_t idport; char name[JACK_PORT_NAME_SIZE]; //portname int IsConnected; int IsUnregistered; } PortFollower; /*! \brief A "decorator" debug client to validate API use. */ class JackDebugClient : public JackClient { protected: JackClient* fClient; std::ofstream* fStream; PortFollower fPortList[MAX_PORT_HISTORY]; // Arbitrary value... To be tuned... int fTotalPortNumber; // The total number of port opened and maybe closed. Historical view. int fOpenPortNumber; // The current number of opened port. int fIsActivated; int fIsDeactivated; int fIsClosed; bool fFreewheel; char fClientName[JACK_CLIENT_NAME_SIZE+1]; JackProcessCallback fProcessTimeCallback; void* fProcessTimeCallbackArg; public: JackDebugClient(JackClient* fTheClient); virtual ~JackDebugClient(); virtual int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); int Close(); virtual JackGraphManager* GetGraphManager() const; virtual JackEngineControl* GetEngineControl() const; // Notifications int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); int Activate(); int Deactivate(); // Context int SetBufferSize(jack_nframes_t buffer_size); int SetFreeWheel(int onoff); int ComputeTotalLatencies(); void ShutDown(jack_status_t code, const char* message); jack_native_thread_t GetThreadID(); // Port management int PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size); int PortUnRegister(jack_port_id_t port); int PortConnect(const char* src, const char* dst); int PortDisconnect(const char* src, const char* dst); int PortDisconnect(jack_port_id_t src); int PortIsMine(jack_port_id_t port_index); int PortRename(jack_port_id_t port_index, const char* name); // Transport int ReleaseTimebase(); int SetSyncCallback(JackSyncCallback sync_callback, void* arg); int SetSyncTimeout(jack_time_t timeout); int SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg); void TransportLocate(jack_nframes_t frame); jack_transport_state_t TransportQuery(jack_position_t* pos); jack_nframes_t GetCurrentTransportFrame(); int TransportReposition(const jack_position_t* pos); void TransportStart(); void TransportStop(); // Callbacks void OnShutdown(JackShutdownCallback callback, void *arg); void OnInfoShutdown(JackInfoShutdownCallback callback, void *arg); int SetProcessCallback(JackProcessCallback callback, void* arg); int SetXRunCallback(JackXRunCallback callback, void* arg); int SetInitCallback(JackThreadInitCallback callback, void* arg); int SetGraphOrderCallback(JackGraphOrderCallback callback, void* arg); int SetBufferSizeCallback(JackBufferSizeCallback callback, void* arg); int SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg); int SetFreewheelCallback(JackFreewheelCallback callback, void* arg); int SetPortRegistrationCallback(JackPortRegistrationCallback callback, void* arg); int SetPortConnectCallback(JackPortConnectCallback callback, void *arg); int SetPortRenameCallback(JackPortRenameCallback callback, void *arg); int SetSessionCallback(JackSessionCallback callback, void *arg); int SetLatencyCallback(JackLatencyCallback callback, void *arg); // Internal clients char* GetInternalClientName(int ref); int InternalClientHandle(const char* client_name, jack_status_t* status); int InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va); void InternalClientUnload(int ref, jack_status_t* status); // RT Thread int SetProcessThread(JackThreadCallback fun, void *arg); // Session API jack_session_command_t* SessionNotify(const char* target, jack_session_event_type_t type, const char* path); int SessionReply(jack_session_event_t* ev); char* GetUUIDForClientName(const char* client_name); char* GetClientNameByUUID(const char* uuid); int ReserveClientName(const char* client_name, const char* uuid); int ClientHasSessionCallback(const char* client_name); JackClientControl* GetClientControl() const; void CheckClient(const char* function_name) const; static int TimeCallback(jack_nframes_t nframes, void *arg); }; } // end of namespace #endif 1.9.12~dfsg/common/JackActivationCount.h0000644000000000000000000000322113214314510016702 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackActivationCount__ #define __JackActivationCount__ #include "JackPlatformPlug.h" #include "JackTime.h" #include "JackTypes.h" namespace Jack { struct JackClientControl; /*! \brief Client activation counter. */ PRE_PACKED_STRUCTURE class JackActivationCount { private: SInt32 fValue; SInt32 fCount; public: JackActivationCount(): fValue(0), fCount(0) {} bool Signal(JackSynchro* synchro, JackClientControl* control); inline void Reset() { fValue = fCount; } inline void SetValue(int val) { fCount = val; } inline void IncValue() { fCount++; } inline void DecValue() { fCount--; } inline int GetValue() const { return fValue; } } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/common/JackPortType.h0000644000000000000000000000263713214314510015370 0ustar rootroot/* Copyright (C) 2007 Dmitry Baikov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPortType__ #define __JackPortType__ #include "types.h" #include "JackConstants.h" #include namespace Jack { extern jack_port_type_id_t PORT_TYPES_MAX; struct JackPortType { const char* fName; size_t (*size)(); void (*init)(void* buffer, size_t buffer_size, jack_nframes_t nframes); void (*mixdown)(void *mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes); }; extern jack_port_type_id_t GetPortTypeId(const char* port_type); extern const struct JackPortType* GetPortType(jack_port_type_id_t port_type_id); extern const struct JackPortType gAudioPortType; extern const struct JackPortType gMidiPortType; } // namespace Jack #endif 1.9.12~dfsg/common/JackAudioDriver.cpp0000644000000000000000000003166313214314510016353 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the (at your option) any later version. GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackSystemDeps.h" #include "JackAudioDriver.h" #include "JackTime.h" #include "JackError.h" #include "JackEngineControl.h" #include "JackPort.h" #include "JackGraphManager.h" #include "JackLockedEngine.h" #include "JackException.h" #include using namespace std; namespace Jack { JackAudioDriver::JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackDriver(name, alias, engine, table) {} JackAudioDriver::~JackAudioDriver() {} int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size) { // Update engine and graph manager state fEngineControl->fBufferSize = buffer_size; fGraphManager->SetBufferSize(buffer_size); fEngineControl->UpdateTimeOut(); UpdateLatencies(); // Redirected on slaves drivers... return JackDriver::SetBufferSize(buffer_size); } int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate) { fEngineControl->fSampleRate = sample_rate; fEngineControl->UpdateTimeOut(); // Redirected on slaves drivers... return JackDriver::SetSampleRate(sample_rate); } int JackAudioDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { fCaptureChannels = inchannels; fPlaybackChannels = outchannels; fWithMonitorPorts = monitor; memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } void JackAudioDriver::UpdateLatencies() { jack_latency_range_t input_range; jack_latency_range_t output_range; jack_latency_range_t monitor_range; for (int i = 0; i < fCaptureChannels; i++) { input_range.max = input_range.min = fEngineControl->fBufferSize + fCaptureLatency; fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); } for (int i = 0; i < fPlaybackChannels; i++) { output_range.max = output_range.min = fPlaybackLatency; if (fEngineControl->fSyncMode) { output_range.max = output_range.min += fEngineControl->fBufferSize; } else { output_range.max = output_range.min += fEngineControl->fBufferSize * 2; } fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); if (fWithMonitorPorts) { monitor_range.min = monitor_range.max = fEngineControl->fBufferSize; fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range); } } } int JackAudioDriver::Attach() { JackPort* port; jack_port_id_t port_index; char name[REAL_JACK_PORT_NAME_SIZE+1]; char alias[REAL_JACK_PORT_NAME_SIZE+1]; int i; jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fCapturePortList[i] = port_index; jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } for (i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fPlaybackPortList[i] = port_index; jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); // Monitor ports if (fWithMonitorPorts) { jack_log("Create monitor port"); snprintf(name, sizeof(name), "%s:monitor_%u", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("Cannot register monitor port for %s", name); return -1; } else { fMonitorPortList[i] = port_index; } } } UpdateLatencies(); return 0; } int JackAudioDriver::Detach() { int i; jack_log("JackAudioDriver::Detach"); for (i = 0; i < fCaptureChannels; i++) { fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[i]); } for (i = 0; i < fPlaybackChannels; i++) { fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[i]); if (fWithMonitorPorts) { fEngine->PortUnRegister(fClientControl.fRefNum, fMonitorPortList[i]); } } return 0; } int JackAudioDriver::Write() { for (int i = 0; i < fPlaybackChannels; i++) { if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { jack_default_audio_sample_t* buffer = GetOutputBuffer(i); int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; // Monitor ports if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) { memcpy(GetMonitorBuffer(i), buffer, size); } } } return 0; } int JackAudioDriver::Process() { return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); } /* The driver "asynchronous" mode: output buffers computed at the *previous cycle* are used, the server does not synchronize to the end of client graph execution. */ int JackAudioDriver::ProcessAsync() { // Read input buffers for the current cycle if (Read() < 0) { jack_error("JackAudioDriver::ProcessAsync: read error, stopping..."); return -1; } // Write output buffers from the previous cycle if (Write() < 0) { jack_error("JackAudioDriver::ProcessAsync: write error, stopping..."); return -1; } // Process graph ProcessGraphAsync(); // Keep end cycle time JackDriver::CycleTakeEndTime(); return 0; } void JackAudioDriver::ProcessGraphAsync() { // Process graph if (fIsMaster) { ProcessGraphAsyncMaster(); } else { ProcessGraphAsyncSlave(); } } /* Used when the driver works in master mode. */ void JackAudioDriver::ProcessGraphAsyncMaster() { // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle if (!fEngine->Process(fBeginDateUst, fEndDateUst)) { jack_error("JackAudioDriver::ProcessGraphAsyncMaster: Process error"); } if (ResumeRefNum() < 0) { jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ResumeRefNum error"); } if (ProcessReadSlaves() < 0) { jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessReadSlaves error"); } if (ProcessWriteSlaves() < 0) { jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessWriteSlaves error"); } // Does not wait on graph execution end } /* Used when the driver works in slave mode. */ void JackAudioDriver::ProcessGraphAsyncSlave() { if (ResumeRefNum() < 0) { jack_error("JackAudioDriver::ProcessGraphAsyncSlave: ResumeRefNum error"); } } /* The driver "synchronous" mode: the server does synchronize to the end of client graph execution, if graph process succeed, output buffers computed at the *current cycle* are used. */ int JackAudioDriver::ProcessSync() { // Read input buffers for the current cycle if (Read() < 0) { jack_error("JackAudioDriver::ProcessSync: read error, stopping..."); return -1; } // Process graph ProcessGraphSync(); // Write output buffers from the current cycle if (Write() < 0) { jack_error("JackAudioDriver::ProcessSync: write error, stopping..."); return -1; } // Keep end cycle time JackDriver::CycleTakeEndTime(); return 0; } void JackAudioDriver::ProcessGraphSync() { // Process graph if (fIsMaster) { ProcessGraphSyncMaster(); } else { ProcessGraphSyncSlave(); } } /* Used when the driver works in master mode. */ void JackAudioDriver::ProcessGraphSyncMaster() { // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle if (fEngine->Process(fBeginDateUst, fEndDateUst)) { if (ResumeRefNum() < 0) { jack_error("JackAudioDriver::ProcessGraphSyncMaster: ResumeRefNum error"); } if (ProcessReadSlaves() < 0) { jack_error("JackAudioDriver::ProcessGraphSync: ProcessReadSlaves error, engine may now behave abnormally!!"); } if (ProcessWriteSlaves() < 0) { jack_error("JackAudioDriver::ProcessGraphSync: ProcessWriteSlaves error, engine may now behave abnormally!!"); } // Waits for graph execution end if (SuspendRefNum() < 0) { jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!"); } } else { // Graph not finished: do not activate it jack_error("JackAudioDriver::ProcessGraphSync: Process error"); } } /* Used when the driver works in slave mode. */ void JackAudioDriver::ProcessGraphSyncSlave() { if (ResumeRefNum() < 0) { jack_error("JackAudioDriver::ProcessGraphSyncSlave: ResumeRefNum error"); } } jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index) { return fCapturePortList[port_index] ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize) : NULL; } jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index) { return fPlaybackPortList[port_index] ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize) : NULL; } jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) { return fPlaybackPortList[port_index] ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize) : NULL; } int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { switch (notify) { case kLatencyCallback: HandleLatencyCallback(value1); break; default: JackDriver::ClientNotify(refnum, name, notify, sync, message, value1, value2); break; } return 0; } void JackAudioDriver::HandleLatencyCallback(int status) { jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; for (int i = 0; i < fCaptureChannels; i++) { if (mode == JackPlaybackLatency) { fGraphManager->RecalculateLatency(fCapturePortList[i], mode); } } for (int i = 0; i < fPlaybackChannels; i++) { if (mode == JackCaptureLatency) { fGraphManager->RecalculateLatency(fPlaybackPortList[i], mode); } } } } // end of namespace 1.9.12~dfsg/common/JackAtomicArrayState.h0000644000000000000000000002016513214314510017012 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAtomicArrayState__ #define __JackAtomicArrayState__ #include "JackAtomic.h" #include "JackCompilerDeps.h" #include // for memcpy namespace Jack { /*! \brief Counter for CAS */ PRE_PACKED_STRUCTURE struct AtomicArrayCounter { union { struct { unsigned char fByteVal[4]; } scounter; UInt32 fLongVal; }info; AtomicArrayCounter() { info.fLongVal = 0; } AtomicArrayCounter(volatile const AtomicArrayCounter& obj) { info.fLongVal = obj.info.fLongVal; } AtomicArrayCounter(volatile AtomicArrayCounter& obj) { info.fLongVal = obj.info.fLongVal; } AtomicArrayCounter& operator=(volatile AtomicArrayCounter& obj) { info.fLongVal = obj.info.fLongVal; return *this; } AtomicArrayCounter& operator=(AtomicArrayCounter& obj) { info.fLongVal = obj.info.fLongVal; return *this; } } POST_PACKED_STRUCTURE; #define Counter1(e) (e).info.fLongVal #define GetIndex1(e, state) ((e).info.scounter.fByteVal[state]) #define SetIndex1(e, state, val) ((e).info.scounter.fByteVal[state] = val) #define IncIndex1(e, state) ((e).info.scounter.fByteVal[state]++) #define SwapIndex1(e, state) (((e).info.scounter.fByteVal[0] == state) ? 0 : state) /*! \brief A class to handle several states in a lock-free manner Requirement: - a "current" state - several possible "pending" state - an TrySwitchState(int state) operation to atomically switch a "pending" to the "current" state (the pending becomes the current). The TrySwitchState operation returns a "current" state (either the same if switch fails or the new one, one can know if the switch has succeeded) - a WriteNextStartState(int state) returns a "pending" state to be written into - a WriteNextStartStop(int state) make the written "pending" state become "switchable" Different pending states can be written independantly and concurrently. GetCurrentIndex() *must* return an increasing value to be able to check reading current state coherency The fCounter is an array of indexes to access the current and 3 different "pending" states. WriteNextStateStart(int index) must return a valid state to be written into, and must invalidate state "index" ==> cur state switch. WriteNextStateStop(int index) makes the "index" state become "switchable" with the current state. TrySwitchState(int index) must detect that pending state is a new state, and does the switch ReadCurrentState() must return the state GetCurrentIndex() must return an index increased each new switch. WriteNextStateStart(int index1) and WriteNextStateStart(int index2) can be interleaved [switch counter][index state][index state][cur index] */ // CHECK livelock PRE_PACKED_STRUCTURE template class JackAtomicArrayState { protected: // fState[0] ==> current // fState[1] ==> pending // fState[2] ==> request T fState[3]; volatile AtomicArrayCounter fCounter; UInt32 WriteNextStateStartAux(int state, bool* result) { AtomicArrayCounter old_val; AtomicArrayCounter new_val; UInt32 cur_index; UInt32 next_index; bool need_copy; do { old_val = fCounter; new_val = old_val; *result = GetIndex1(new_val, state); cur_index = GetIndex1(new_val, 0); next_index = SwapIndex1(fCounter, state); need_copy = (GetIndex1(new_val, state) == 0); // Written = false, switch just occured SetIndex1(new_val, state, 0); // Written = false, invalidate state } while (!CAS(Counter1(old_val), Counter1(new_val), (UInt32*)&fCounter)); if (need_copy) memcpy(&fState[next_index], &fState[cur_index], sizeof(T)); return next_index; } void WriteNextStateStopAux(int state) { AtomicArrayCounter old_val; AtomicArrayCounter new_val; do { old_val = fCounter; new_val = old_val; SetIndex1(new_val, state, 1); // Written = true, state becomes "switchable" } while (!CAS(Counter1(old_val), Counter1(new_val), (UInt32*)&fCounter)); } public: JackAtomicArrayState() { Counter1(fCounter) = 0; } ~JackAtomicArrayState() // Not virtual ?? {} /*! \brief Returns the current state : only valid in the RT reader thread */ T* ReadCurrentState() { return &fState[GetIndex1(fCounter, 0)]; } /*! \brief Returns the current switch counter */ UInt16 GetCurrentIndex() { return GetIndex1(fCounter, 3); } /*! \brief Tries to switch to the next state and returns the new current state (either the same as before if case of switch failure or the new one) */ T* TrySwitchState(int state) { AtomicArrayCounter old_val; AtomicArrayCounter new_val; do { old_val = fCounter; new_val = old_val; if (GetIndex1(new_val, state)) { // If state has been written SetIndex1(new_val, 0, SwapIndex1(new_val, state)); // Prepare switch SetIndex1(new_val, state, 0); // Invalidate the state "state" IncIndex1(new_val, 3); // Inc switch } } while (!CAS(Counter1(old_val), Counter1(new_val), (UInt32*)&fCounter)); return &fState[GetIndex1(fCounter, 0)]; // Read the counter again } /*! \brief Tries to switch to the next state and returns the new current state (either the same as before if case of switch failure or the new one) */ T* TrySwitchState(int state, bool* result) { AtomicArrayCounter old_val; AtomicArrayCounter new_val; do { old_val = fCounter; new_val = old_val; if ((*result = GetIndex1(new_val, state))) { // If state has been written SetIndex1(new_val, 0, SwapIndex1(new_val, state)); // Prepare switch SetIndex1(new_val, state, 0); // Invalidate the state "state" IncIndex1(new_val, 3); // Inc switch } } while (!CAS(Counter1(old_val), Counter1(new_val), (UInt32*)&fCounter)); return &fState[GetIndex1(fCounter, 0)]; // Read the counter again } /*! \brief Start write operation : setup and returns the next state to update, check for recursive write calls. */ T* WriteNextStateStart(int state) { bool tmp; UInt32 index = WriteNextStateStartAux(state, &tmp); return &fState[index]; } T* WriteNextStateStart(int state, bool* result) { UInt32 index = WriteNextStateStartAux(state, result); return &fState[index]; } /*! \brief Stop write operation : make the next state ready to be used by the RT thread */ void WriteNextStateStop(int state) { WriteNextStateStopAux(state); } } POST_PACKED_STRUCTURE; } // end of namespace #endif 1.9.12~dfsg/.wafupdaterc0000755000000000000000000000323513214314510013654 0ustar rootroot# This file is sourced by wafupdate when waf is updated. # wafupdate home page: https://gitlab.com/karllinden/wafupdate WAFLIB_STRIP_TOOLS=" asm bison compiler_d compiler_fc cs d d_config d_scan dbus dmd fc fc_config fc_scan flex g95 gas gdc gfortran glib2 gnu_dirs ifort intltool javaw kde4 ldc2 lua nasm perl python qt4 qt5 ruby tex vala winres " WAFLIB_STRIP_EXTRAS=" add_objects biber bjam blender boo boost c_dumbpreproc c_emscripten cabal cfg_altoptions cfg_cross_gnu clang_compilation_database codelite compat15 color_gcc color_rvct cppcheck cpplint cython dcc distnet doxygen dpapi eclipse erlang fc_bgxlf fc_cray fc_nag fc_nec fc_open64 fc_pgfortran fc_solstudio fc_xlf file_to_object fluid freeimage fsb fsc gccdeps go gob2 halide local_rpath make md5_tstamp mem_reducer midl misc msvcdeps msvs netcache_client nobuild objcopy ocaml package parallel_debug pch pep8 pgicc pgicxx prefork preforkjava preforkunix print_commands proc protoc qnxnto relocation remote resx review rst run_do_script run_m_script run_py_script run_r_script sas scala slow_qt4 smart_continue softlink_libs stale stracedeps swig syms sync_exec ticgt unc unity use_config valadoc why win32_opts " 1.9.12~dfsg/macosx/0000755000000000000000000000000013244556535012654 5ustar rootroot1.9.12~dfsg/macosx/JackAtomic_os.h0000644000000000000000000000412013214314510015506 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackAtomic_APPLE__ #define __JackAtomic_APPLE__ #include "JackTypes.h" #if defined(__ppc__) || defined(__ppc64__) static inline int CAS(register UInt32 value, register UInt32 newvalue, register volatile void* addr) { register int result; asm volatile ( "# CAS \n" " lwarx r0, 0, %1 \n" // creates a reservation on addr " cmpw r0, %2 \n" // test value at addr " bne- 1f \n" " sync \n" // synchronize instructions " stwcx. %3, 0, %1 \n" // if the reservation is not altered // stores the new value at addr " bne- 1f \n" " li %0, 1 \n" " b 2f \n" "1: \n" " li %0, 0 \n" "2: \n" : "=r" (result) : "r" (addr), "r" (value), "r" (newvalue) : "r0" ); return result; } #endif #if defined(__i386__) || defined(__x86_64__) #define LOCK "lock ; " static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) { register char ret; __asm__ __volatile__ ( "# CAS \n\t" LOCK "cmpxchg %2, (%1) \n\t" "sete %0 \n\t" : "=a" (ret) : "c" (addr), "d" (newvalue), "a" (value) ); return ret; } #endif #endif 1.9.12~dfsg/macosx/Jackdmp.xcodeproj/0000755000000000000000000000000013214314510016177 5ustar rootroot1.9.12~dfsg/macosx/Jackdmp.xcodeproj/project.pbxproj0000644000000000000000000311051413214314510021260 0ustar rootroot// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 42; objects = { /* Begin PBXAggregateTarget section */ 4B35C6420D47339B000DE7AE /* All Universal 32/64 bits */ = { isa = PBXAggregateTarget; buildConfigurationList = 4B35C6790D47339B000DE7AE /* Build configuration list for PBXAggregateTarget "All Universal 32/64 bits" */; buildPhases = ( ); dependencies = ( 4B35C6800D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6820D4733B9000DE7AE /* PBXTargetDependency */, 4BB492A71372A393005F2601 /* PBXTargetDependency */, 4B35C67E0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6AC0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6B00D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6B20D4733B9000DE7AE /* PBXTargetDependency */, 4BDCDC2C1002036100B15929 /* PBXTargetDependency */, 4BDCDC2E1002036100B15929 /* PBXTargetDependency */, 4B32259110A31ABA00838A8E /* PBXTargetDependency */, 4B43A8E91014618D00E52943 /* PBXTargetDependency */, 4BDCDC301002036100B15929 /* PBXTargetDependency */, 4BDCDC39100203D500B15929 /* PBXTargetDependency */, 4BDCDC3B100203D500B15929 /* PBXTargetDependency */, 4B35C6860D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6880D4733B9000DE7AE /* PBXTargetDependency */, 4B35C68A0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C68C0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C68E0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6900D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6920D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6940D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6960D4733B9000DE7AE /* PBXTargetDependency */, 4B0A29300D5210C4002EFF74 /* PBXTargetDependency */, 4B35C69C0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C69E0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6A00D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6A20D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6A40D4733B9000DE7AE /* PBXTargetDependency */, 4BFA83320DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA83340DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA83380DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833A0DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833C0DF6AB540087B4E1 /* PBXTargetDependency */, 4B32258F10A31AB400838A8E /* PBXTargetDependency */, 4B66550E127C356E00753A79 /* PBXTargetDependency */, 4B38120313269CCB00C61B14 /* PBXTargetDependency */, 4B8F16FC1329169F0002AD73 /* PBXTargetDependency */, 4B20220C133A9C370019E213 /* PBXTargetDependency */, ); name = "All Universal 32/64 bits"; productName = All; }; 4B699B26097D421600A18468 /* All Universal 32 bits */ = { isa = PBXAggregateTarget; buildConfigurationList = 4B699B33097D421600A18468 /* Build configuration list for PBXAggregateTarget "All Universal 32 bits" */; buildPhases = ( ); dependencies = ( 4B699DB4097D421700A18468 /* PBXTargetDependency */, 4B699DB6097D421700A18468 /* PBXTargetDependency */, 4B699DB8097D421700A18468 /* PBXTargetDependency */, 4B699DBA097D421700A18468 /* PBXTargetDependency */, 4BF339280F8B87800080FB5B /* PBXTargetDependency */, 4B699DBC097D421700A18468 /* PBXTargetDependency */, BA222AF20DC883F3001A17F4 /* PBXTargetDependency */, 4B32258D10A31A9D00838A8E /* PBXTargetDependency */, 4B43A8CD1014607100E52943 /* PBXTargetDependency */, 4BD624D30CBCF55700DE782F /* PBXTargetDependency */, BA222AF00DC883EF001A17F4 /* PBXTargetDependency */, 4B19B32C0E23636E00DD4A82 /* PBXTargetDependency */, 4B224B340E65BA330066BE5B /* PBXTargetDependency */, 4B5A1BE20CD1CD730005BF74 /* PBXTargetDependency */, 4B5A1BCF0CD1CCC80005BF74 /* PBXTargetDependency */, 4BFA99440AAAED90009E916C /* PBXTargetDependency */, 4BFA99460AAAED90009E916C /* PBXTargetDependency */, 4BA7FECD0D8E76810017FF73 /* PBXTargetDependency */, 4BFA99480AAAED90009E916C /* PBXTargetDependency */, 4BFA994A0AAAED90009E916C /* PBXTargetDependency */, 4BFA994C0AAAED90009E916C /* PBXTargetDependency */, 4BFA994E0AAAED90009E916C /* PBXTargetDependency */, 4BFA99560AAAED90009E916C /* PBXTargetDependency */, 4BE99D630AD7A19100C59091 /* PBXTargetDependency */, 4BA693E90CBE5BBA00EAD520 /* PBXTargetDependency */, 4BA693EB0CBE5BBA00EAD520 /* PBXTargetDependency */, 4B0A28F40D520D11002EFF74 /* PBXTargetDependency */, 4B363DE50DEB037F001F72D9 /* PBXTargetDependency */, 4BFA99AC0AAAF41D009E916C /* PBXTargetDependency */, 4BFA99540AAAED90009E916C /* PBXTargetDependency */, 4B363E750DEB0838001F72D9 /* PBXTargetDependency */, 4B363E770DEB0838001F72D9 /* PBXTargetDependency */, 4B363F250DEB0ABE001F72D9 /* PBXTargetDependency */, 4B363F530DEB0CFE001F72D9 /* PBXTargetDependency */, 4B363F780DEB0D85001F72D9 /* PBXTargetDependency */, 4B32258B10A31A9000838A8E /* PBXTargetDependency */, 4B38120113269CB600C61B14 /* PBXTargetDependency */, 4B8F16FA132916910002AD73 /* PBXTargetDependency */, ); name = "All Universal 32 bits"; productName = All; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 4B0A28ED0D520852002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; }; 4B0A29260D52108E002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; }; 4B1499F014BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */; }; 4B1499F114BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */; }; 4B1499F214BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */; }; 4B1499F314BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */; }; 4B1499F414BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */; }; 4B1499F514BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */; }; 4B1499F614BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */; }; 4B1499F714BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */; }; 4B1499F814BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */; }; 4B1499F914BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */; }; 4B1499FA14BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */; }; 4B1499FB14BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */; }; 4B193991133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193992133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193993133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193994133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193995133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193996133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B19B3130E2362E800DD4A82 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; 4B19B3140E2362E800DD4A82 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; 4B19B3150E2362E800DD4A82 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; 4B19B3160E2362E800DD4A82 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; 4B19B31B0E2362E800DD4A82 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; 4B20220A133A9C1C0019E213 /* midi_latency_test.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B202209133A9C1C0019E213 /* midi_latency_test.c */; }; 4B21794F13E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */; }; 4B21795013E2EEA60095B3E5 /* JackTimedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */; }; 4B21795113E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */; }; 4B21795213E2EEA60095B3E5 /* JackTimedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */; }; 4B21795313E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */; }; 4B21795413E2EEA60095B3E5 /* JackTimedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */; }; 4B2209E112F6BBF300E5DC26 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; }; 4B2209E212F6BBF400E5DC26 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; }; 4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; }; 4B2209E412F6BBF600E5DC26 /* JackSocketServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B60E703B8D0066E42F /* JackSocketServerNotifyChannel.h */; }; 4B2209E612F6BC0200E5DC26 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; 4B2209E712F6BC0300E5DC26 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; 4B2209E912F6BC1500E5DC26 /* JackSocketNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B10E703B8D0066E42F /* JackSocketNotifyChannel.cpp */; }; 4B2209EA12F6BC1600E5DC26 /* JackSocketNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B20E703B8D0066E42F /* JackSocketNotifyChannel.h */; }; 4B2209EC12F6BC2100E5DC26 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; 4B2209ED12F6BC2200E5DC26 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; 4B2209EE12F6BC2300E5DC26 /* JackSocketClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AF0E703B8D0066E42F /* JackSocketClientChannel.cpp */; }; 4B2209EF12F6BC2500E5DC26 /* JackSocketClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */; }; 4B3224EA10A315B100838A8E /* JackNetOneDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */; }; 4B3224EB10A315B100838A8E /* JackNetOneDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224E910A315B100838A8E /* JackNetOneDriver.h */; }; 4B3224F010A315C400838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; 4B3224F110A315C400838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; 4B3224F210A315C400838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; 4B3224F310A315C400838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; 4B32253110A3173900838A8E /* JackNetOneDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */; }; 4B32253210A3173A00838A8E /* JackNetOneDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224E910A315B100838A8E /* JackNetOneDriver.h */; }; 4B32253310A3173B00838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; 4B32253410A3173C00838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; 4B32253510A3173D00838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; 4B32253610A3173E00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; 4B32256410A318E300838A8E /* netsource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B32256310A318E300838A8E /* netsource.c */; }; 4B32256D10A318FC00838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; 4B32256E10A318FD00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; 4B32257F10A3195900838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; 4B32258010A3195A00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; 4B32258110A3195B00838A8E /* netsource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B32256310A318E300838A8E /* netsource.c */; }; 4B327BA714B4B50400976483 /* JackPosixMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */; }; 4B327BA814B4B50400976483 /* JackPosixMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */; }; 4B327BA914B4B50400976483 /* JackPosixMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */; }; 4B327BAA14B4B50400976483 /* JackPosixMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */; }; 4B327BAB14B4B50400976483 /* JackPosixMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */; }; 4B327BAC14B4B50400976483 /* JackPosixMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */; }; 4B327BD614B4B6E700976483 /* JackException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B67AB8C14B4B03800B4AA9A /* JackException.cpp */; }; 4B35C41E0D4731D1000DE7AE /* Jackdmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */; }; 4B35C42A0D4731D1000DE7AE /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B35C42B0D4731D1000DE7AE /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B35C42C0D4731D1000DE7AE /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; 4B35C42D0D4731D1000DE7AE /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; 4B35C42F0D4731D1000DE7AE /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; 4B35C4300D4731D1000DE7AE /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; 4B35C4310D4731D1000DE7AE /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; 4B35C4320D4731D1000DE7AE /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; 4B35C4330D4731D1000DE7AE /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; 4B35C4340D4731D1000DE7AE /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; 4B35C4350D4731D1000DE7AE /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; 4B35C4360D4731D1000DE7AE /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; 4B35C4370D4731D1000DE7AE /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; 4B35C4380D4731D1000DE7AE /* JackLibGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FB0834EFD100C94B91 /* JackLibGlobals.h */; }; 4B35C4390D4731D1000DE7AE /* JackLibClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FC0834EFD100C94B91 /* JackLibClient.h */; }; 4B35C43A0D4731D1000DE7AE /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; 4B35C43B0D4731D1000DE7AE /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; 4B35C43D0D4731D1000DE7AE /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4B35C43E0D4731D1000DE7AE /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B35C43F0D4731D1000DE7AE /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; 4B35C4460D4731D1000DE7AE /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4B35C4470D4731D1000DE7AE /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B35C4480D4731D1000DE7AE /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B35C4490D4731D1000DE7AE /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4B35C44A0D4731D1000DE7AE /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C44B0D4731D1000DE7AE /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C44C0D4731D1000DE7AE /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C44D0D4731D1000DE7AE /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C44E0D4731D1000DE7AE /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C44F0D4731D1000DE7AE /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4500D4731D1000DE7AE /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4510D4731D1000DE7AE /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4520D4731D1000DE7AE /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; 4B35C4530D4731D1000DE7AE /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B35C4540D4731D1000DE7AE /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4550D4731D1000DE7AE /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; 4B35C45B0D4731D1000DE7AE /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B35C45C0D4731D1000DE7AE /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B35C45E0D4731D1000DE7AE /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; 4B35C45F0D4731D1000DE7AE /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; 4B35C4600D4731D1000DE7AE /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; 4B35C4610D4731D1000DE7AE /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; 4B35C4620D4731D1000DE7AE /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; 4B35C4630D4731D1000DE7AE /* JackLibClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FD0834EFD100C94B91 /* JackLibClient.cpp */; }; 4B35C4640D4731D1000DE7AE /* JackLibAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FE0834EFD100C94B91 /* JackLibAPI.cpp */; }; 4B35C4650D4731D1000DE7AE /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; 4B35C4660D4731D1000DE7AE /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4B35C4680D4731D1000DE7AE /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B35C4690D4731D1000DE7AE /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; 4B35C4700D4731D1000DE7AE /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B35C4720D4731D1000DE7AE /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B35C4730D4731D1000DE7AE /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; 4B35C4740D4731D1000DE7AE /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4B35C4760D4731D1000DE7AE /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4B35C4770D4731D1000DE7AE /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; 4B35C4780D4731D1000DE7AE /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; 4B35C4790D4731D1000DE7AE /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4B35C47A0D4731D1000DE7AE /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4B35C47B0D4731D1000DE7AE /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; 4B35C47C0D4731D1000DE7AE /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; 4B35C4880D4731D1000DE7AE /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B35C4890D4731D1000DE7AE /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B35C48A0D4731D1000DE7AE /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; 4B35C48B0D4731D1000DE7AE /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; 4B35C48D0D4731D1000DE7AE /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; 4B35C48E0D4731D1000DE7AE /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; 4B35C48F0D4731D1000DE7AE /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; 4B35C4900D4731D1000DE7AE /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; 4B35C4910D4731D1000DE7AE /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; 4B35C4920D4731D1000DE7AE /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; 4B35C4930D4731D1000DE7AE /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; 4B35C4940D4731D1000DE7AE /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; 4B35C4950D4731D1000DE7AE /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; 4B35C4960D4731D1000DE7AE /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; 4B35C4970D4731D1000DE7AE /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; 4B35C4990D4731D1000DE7AE /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4B35C49A0D4731D1000DE7AE /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B35C49B0D4731D1000DE7AE /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; 4B35C4A00D4731D1000DE7AE /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4B35C4A10D4731D1000DE7AE /* JackAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2290834F07D00C94B91 /* JackAudioDriver.h */; }; 4B35C4A20D4731D1000DE7AE /* JackFreewheelDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B90834EEF100C94B91 /* JackFreewheelDriver.h */; }; 4B35C4A30D4731D1000DE7AE /* JackThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1BD0834EEFC00C94B91 /* JackThreadedDriver.h */; }; 4B35C4A40D4731D1000DE7AE /* JackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B50834EEE400C94B91 /* JackDriver.h */; }; 4B35C4A50D4731D1000DE7AE /* driver_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B3D08C8D21C001CF041 /* driver_interface.h */; }; 4B35C4A70D4731D1000DE7AE /* JackDriverLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */; }; 4B35C4A90D4731D1000DE7AE /* JackEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2130834F02800C94B91 /* JackEngine.h */; }; 4B35C4AA0D4731D1000DE7AE /* JackExternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */; }; 4B35C4AB0D4731D1000DE7AE /* JackServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2220834F05C00C94B91 /* JackServer.h */; }; 4B35C4B20D4731D1000DE7AE /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B35C4B30D4731D1000DE7AE /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4B35C4B40D4731D1000DE7AE /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; 4B35C4B50D4731D1000DE7AE /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4B60D4731D1000DE7AE /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4B70D4731D1000DE7AE /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4B80D4731D1000DE7AE /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4B90D4731D1000DE7AE /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4BA0D4731D1000DE7AE /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4BB0D4731D1000DE7AE /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4BC0D4731D1000DE7AE /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4BD0D4731D1000DE7AE /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; 4B35C4BE0D4731D1000DE7AE /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B35C4BF0D4731D1000DE7AE /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4C00D4731D1000DE7AE /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B35C4C10D4731D1000DE7AE /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; 4B35C4C50D4731D1000DE7AE /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B35C4C60D4731D1000DE7AE /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B35C4C80D4731D1000DE7AE /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; 4B35C4C90D4731D1000DE7AE /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; 4B35C4CA0D4731D1000DE7AE /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; 4B35C4CB0D4731D1000DE7AE /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; 4B35C4CC0D4731D1000DE7AE /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; 4B35C4CD0D4731D1000DE7AE /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; 4B35C4CE0D4731D1000DE7AE /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4B35C4D00D4731D1000DE7AE /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B35C4D10D4731D1000DE7AE /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; 4B35C4D50D4731D1000DE7AE /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B35C4D70D4731D1000DE7AE /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B35C4D80D4731D1000DE7AE /* JackAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D22A0834F07D00C94B91 /* JackAudioDriver.cpp */; }; 4B35C4D90D4731D1000DE7AE /* JackFreewheelDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BA0834EEF100C94B91 /* JackFreewheelDriver.cpp */; }; 4B35C4DA0D4731D1000DE7AE /* JackThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BE0834EEFC00C94B91 /* JackThreadedDriver.cpp */; }; 4B35C4DB0D4731D1000DE7AE /* JackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */; }; 4B35C4DC0D4731D1000DE7AE /* JackDriverLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */; }; 4B35C4DD0D4731D1000DE7AE /* JackEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2140834F02800C94B91 /* JackEngine.cpp */; }; 4B35C4DE0D4731D1000DE7AE /* JackExternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */; }; 4B35C4DF0D4731D1000DE7AE /* JackInternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */; }; 4B35C4E20D4731D1000DE7AE /* JackServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2210834F05C00C94B91 /* JackServer.cpp */; }; 4B35C4EB0D4731D1000DE7AE /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4B35C4EC0D4731D1000DE7AE /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; 4B35C4ED0D4731D1000DE7AE /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; 4B35C4EE0D4731D1000DE7AE /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4B35C4EF0D4731D1000DE7AE /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; 4B35C4F00D4731D1000DE7AE /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; 4B35C4F10D4731D1000DE7AE /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4B35C4F20D4731D1000DE7AE /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4B35C4F30D4731D1000DE7AE /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; 4B35C4F40D4731D1000DE7AE /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; 4B35C4F50D4731D1000DE7AE /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; 4B35C50D0D4731D1000DE7AE /* midiseq.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A1BBD0CD1CC110005BF74 /* midiseq.c */; }; 4B35C5190D4731D1000DE7AE /* midisine.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A1BDC0CD1CD420005BF74 /* midisine.c */; }; 4B35C5250D4731D1000DE7AE /* metro.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D16B0834EDF000C94B91 /* metro.c */; }; 4B35C5310D4731D1000DE7AE /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1690834EDE600C94B91 /* lsp.c */; }; 4B35C53D0D4731D1000DE7AE /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; }; 4B35C5490D4731D1000DE7AE /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; }; 4B35C5570D4731D2000DE7AE /* freewheel.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1710834EE0F00C94B91 /* freewheel.c */; }; 4B35C57D0D4731D2000DE7AE /* testAtomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D23E0834F1C300C94B91 /* testAtomic.cpp */; }; 4B35C58D0D4731D2000DE7AE /* testSem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2470834F20600C94B91 /* testSem.cpp */; }; 4B35C59F0D4731D2000DE7AE /* zombie.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1670834EDD900C94B91 /* zombie.c */; }; 4B35C5AB0D4731D2000DE7AE /* test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6C6AC0A3E0A65005A203A /* test.cpp */; }; 4B35C5B70D4731D2000DE7AE /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F49070AD8503300491C6E /* cpu.c */; }; 4B35C5C30D4731D2000DE7AE /* ipload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692B20CBE4C2D00EAD520 /* ipload.c */; }; 4B35C5CF0D4731D2000DE7AE /* ipunload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692D60CBE4CC600EAD520 /* ipunload.c */; }; 4B35C5DA0D4731D2000DE7AE /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B35C5DB0D4731D2000DE7AE /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B35C5DD0D4731D2000DE7AE /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B35C5E00D4731D2000DE7AE /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; 4B35C5E20D4731D2000DE7AE /* testSynchroServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */; }; 4B35C5F60D4731D2000DE7AE /* testSynchroClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */; }; 4B35C60A0D4731D2000DE7AE /* testSynchroServerClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBD13CC08C71EB40079F7FF /* testSynchroServerClient.cpp */; }; 4B35C62C0D4731D2000DE7AE /* JackDummyDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */; }; 4B35C62E0D4731D2000DE7AE /* JackDummyDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */; }; 4B35C6380D4731D3000DE7AE /* inprocess.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BD6240C0CBCF16600DE782F /* inprocess.c */; }; 4B363DDF0DEB034E001F72D9 /* alias.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363DDE0DEB034E001F72D9 /* alias.c */; }; 4B363E210DEB0401001F72D9 /* evmon.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363E200DEB0401001F72D9 /* evmon.c */; }; 4B363E720DEB0808001F72D9 /* bufsize.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363E710DEB0808001F72D9 /* bufsize.c */; }; 4B363EEE0DEB094B001F72D9 /* capture_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363EED0DEB094B001F72D9 /* capture_client.c */; }; 4B363F230DEB0AB0001F72D9 /* monitor_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F220DEB0AB0001F72D9 /* monitor_client.c */; }; 4B363F3E0DEB0C31001F72D9 /* showtime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F3D0DEB0C31001F72D9 /* showtime.c */; }; 4B363F760DEB0D7D001F72D9 /* impulse_grabber.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */; }; 4B370A24133DD7E300237B68 /* JackCoreMidiInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */; }; 4B370A25133DD7E300237B68 /* JackCoreMidiInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */; }; 4B370A26133DD7E300237B68 /* JackCoreMidiOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */; }; 4B370A27133DD7E300237B68 /* JackCoreMidiOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A17133DD7E200237B68 /* JackCoreMidiOutputPort.h */; }; 4B370A28133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A18133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.cpp */; }; 4B370A29133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A19133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.h */; }; 4B370A2A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp */; }; 4B370A2B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h */; }; 4B370A2C133DD7E300237B68 /* JackCoreMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1C133DD7E300237B68 /* JackCoreMidiPort.cpp */; }; 4B370A2D133DD7E300237B68 /* JackCoreMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1D133DD7E300237B68 /* JackCoreMidiPort.h */; }; 4B370A2E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1E133DD7E300237B68 /* JackCoreMidiUtil.cpp */; }; 4B370A2F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1F133DD7E300237B68 /* JackCoreMidiUtil.h */; }; 4B370A30133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A20133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp */; }; 4B370A31133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A21133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h */; }; 4B370A32133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A22133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp */; }; 4B370A33133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A23133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h */; }; 4B370A34133DD7E300237B68 /* JackCoreMidiInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */; }; 4B370A35133DD7E300237B68 /* JackCoreMidiInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */; }; 4B370A36133DD7E300237B68 /* JackCoreMidiOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */; }; 4B370A37133DD7E300237B68 /* JackCoreMidiOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A17133DD7E200237B68 /* JackCoreMidiOutputPort.h */; }; 4B370A38133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A18133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.cpp */; }; 4B370A39133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A19133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.h */; }; 4B370A3A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp */; }; 4B370A3B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h */; }; 4B370A3C133DD7E300237B68 /* JackCoreMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1C133DD7E300237B68 /* JackCoreMidiPort.cpp */; }; 4B370A3D133DD7E300237B68 /* JackCoreMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1D133DD7E300237B68 /* JackCoreMidiPort.h */; }; 4B370A3E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1E133DD7E300237B68 /* JackCoreMidiUtil.cpp */; }; 4B370A3F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1F133DD7E300237B68 /* JackCoreMidiUtil.h */; }; 4B370A40133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A20133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp */; }; 4B370A41133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A21133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h */; }; 4B370A42133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A22133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp */; }; 4B370A43133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A23133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h */; }; 4B3811FB13269C8300C61B14 /* latent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3811FA13269C8300C61B14 /* latent_client.c */; }; 4B3811FC13269C8300C61B14 /* latent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3811FA13269C8300C61B14 /* latent_client.c */; }; 4B3814201327AA6800C61B14 /* iodelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38141F1327AA6800C61B14 /* iodelay.cpp */; }; 4B3814211327AA6800C61B14 /* iodelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38141F1327AA6800C61B14 /* iodelay.cpp */; }; 4B3F49080AD8503300491C6E /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F49070AD8503300491C6E /* cpu.c */; }; 4B43A8CA1014605000E52943 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */; }; 4B43A8CB1014605000E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; 4B43A8DF1014615800E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; 4B43A8E11014615800E52943 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */; }; 4B47AC8310B5890100469C67 /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B47AC8410B5890100469C67 /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B47AC8510B5890100469C67 /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; 4B47AC8610B5890100469C67 /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; 4B47AC8710B5890100469C67 /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; 4B47AC8810B5890100469C67 /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; 4B47AC8910B5890100469C67 /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; 4B47AC8A10B5890100469C67 /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; 4B47AC8B10B5890100469C67 /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; 4B47AC8C10B5890100469C67 /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; 4B47AC8D10B5890100469C67 /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; 4B47AC8E10B5890100469C67 /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; 4B47AC8F10B5890100469C67 /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; 4B47AC9010B5890100469C67 /* JackLibGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FB0834EFD100C94B91 /* JackLibGlobals.h */; }; 4B47AC9110B5890100469C67 /* JackLibClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FC0834EFD100C94B91 /* JackLibClient.h */; }; 4B47AC9210B5890100469C67 /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; 4B47AC9310B5890100469C67 /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; 4B47AC9410B5890100469C67 /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4B47AC9510B5890100469C67 /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B47AC9610B5890100469C67 /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; 4B47AC9810B5890100469C67 /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4B47AC9910B5890100469C67 /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B47AC9A10B5890100469C67 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B47AC9B10B5890100469C67 /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4B47AC9C10B5890100469C67 /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47AC9D10B5890100469C67 /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47AC9E10B5890100469C67 /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47AC9F10B5890100469C67 /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47ACA010B5890100469C67 /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47ACA110B5890100469C67 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47ACA210B5890100469C67 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47ACA310B5890100469C67 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47ACA410B5890100469C67 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; 4B47ACA510B5890100469C67 /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B47ACA610B5890100469C67 /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47ACA710B5890100469C67 /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; 4B47ACA810B5890100469C67 /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B47ACA910B5890100469C67 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B47ACAA10B5890100469C67 /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B47ACB110B5890100469C67 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B47ACB210B5890100469C67 /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B47ACB310B5890100469C67 /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; 4B47ACB410B5890100469C67 /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; 4B47ACB510B5890100469C67 /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; 4B47ACB610B5890100469C67 /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; 4B47ACB710B5890100469C67 /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; 4B47ACB810B5890100469C67 /* JackLibClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FD0834EFD100C94B91 /* JackLibClient.cpp */; }; 4B47ACB910B5890100469C67 /* JackLibAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FE0834EFD100C94B91 /* JackLibAPI.cpp */; }; 4B47ACBA10B5890100469C67 /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; 4B47ACBB10B5890100469C67 /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4B47ACBC10B5890100469C67 /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B47ACBD10B5890100469C67 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; 4B47ACBF10B5890100469C67 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B47ACC010B5890100469C67 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B47ACC110B5890100469C67 /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; 4B47ACC210B5890100469C67 /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4B47ACC310B5890100469C67 /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4B47ACC410B5890100469C67 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; 4B47ACC510B5890100469C67 /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; 4B47ACC610B5890100469C67 /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4B47ACC710B5890100469C67 /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4B47ACC810B5890100469C67 /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; 4B47ACC910B5890100469C67 /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; 4B47ACCA10B5890100469C67 /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B47ACCB10B5890100469C67 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4B47ACCC10B5890100469C67 /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; 4B47ACCD10B5890100469C67 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4B47ACCE10B5890100469C67 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4B47ACD210B5890100469C67 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4B49D44214865F22003390F8 /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44014865F22003390F8 /* net.h */; }; 4B49D44314865F22003390F8 /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44114865F22003390F8 /* session.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49D44414865F22003390F8 /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44014865F22003390F8 /* net.h */; }; 4B49D44514865F22003390F8 /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44114865F22003390F8 /* session.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49D44614865F22003390F8 /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44014865F22003390F8 /* net.h */; }; 4B49D44714865F22003390F8 /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44114865F22003390F8 /* session.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49D44814865F22003390F8 /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44014865F22003390F8 /* net.h */; }; 4B49D44914865F22003390F8 /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44114865F22003390F8 /* session.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49D44A14865F22003390F8 /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44014865F22003390F8 /* net.h */; }; 4B49D44B14865F22003390F8 /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44114865F22003390F8 /* session.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49D44C14865F22003390F8 /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44014865F22003390F8 /* net.h */; }; 4B49D44D14865F22003390F8 /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44114865F22003390F8 /* session.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49D44E14865F22003390F8 /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44014865F22003390F8 /* net.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B49D44F14865F22003390F8 /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B49D44114865F22003390F8 /* session.h */; }; 4B4C3B641BC2FF670004CC35 /* JackPosixSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B70E703BAA0066E42F /* JackPosixSemaphore.cpp */; }; 4B4C3B651BC2FF6A0004CC35 /* JackPosixSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B80E703BAA0066E42F /* JackPosixSemaphore.h */; }; 4B4C3B6A1BC2FFB30004CC35 /* JackPosixSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B70E703BAA0066E42F /* JackPosixSemaphore.cpp */; }; 4B4C3B6B1BC2FFB50004CC35 /* JackPosixSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B80E703BAA0066E42F /* JackPosixSemaphore.h */; }; 4B4C3B6C1BC2FFC40004CC35 /* JackPosixSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B70E703BAA0066E42F /* JackPosixSemaphore.cpp */; }; 4B4C3B6D1BC2FFC70004CC35 /* JackPosixSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B80E703BAA0066E42F /* JackPosixSemaphore.h */; }; 4B4C3B6E1BC2FFDD0004CC35 /* JackPosixSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B70E703BAA0066E42F /* JackPosixSemaphore.cpp */; }; 4B4C3B6F1BC2FFE00004CC35 /* JackPosixSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B80E703BAA0066E42F /* JackPosixSemaphore.h */; }; 4B4CA9750E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; 4B4CA9760E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */; }; 4B4CA9770E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; 4B4CA9780E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */; }; 4B4E9AFA0E5F1090000A3278 /* JackControlAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */; }; 4B4E9AFB0E5F1090000A3278 /* JackControlAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4E9AF90E5F1090000A3278 /* JackControlAPI.h */; }; 4B4E9AFC0E5F1090000A3278 /* JackControlAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */; }; 4B4E9AFD0E5F1090000A3278 /* JackControlAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4E9AF90E5F1090000A3278 /* JackControlAPI.h */; }; 4B4F9C8C0DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4B4F9C8D0DC20C0400706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B4F9C8E0DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4B4F9C8F0DC20C0400706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B4F9C900DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4B4F9C910DC20C0400706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B4F9C920DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4B4F9C930DC20C0400706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B4F9D820DC2178E00706CB0 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4B4F9D830DC2178F00706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B5160A813215E8B00BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5160A913215EBF00BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5A1BBE0CD1CC110005BF74 /* midiseq.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A1BBD0CD1CC110005BF74 /* midiseq.c */; }; 4B5A1BDD0CD1CD420005BF74 /* midisine.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A1BDC0CD1CD420005BF74 /* midisine.c */; }; 4B5DB9830CD2429A00EBA5EE /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; 4B5DB9840CD2429B00EBA5EE /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B5E08C30E5B66EE00BEE4E0 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; 4B5E08C60E5B66EE00BEE4E0 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B5E08CC0E5B66EE00BEE4E0 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; 4B5E08CD0E5B66EE00BEE4E0 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B5E08CE0E5B66EE00BEE4E0 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; 4B5E08E10E5B676C00BEE4E0 /* JackNetAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */; }; 4B5E08E20E5B676D00BEE4E0 /* JackNetAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */; }; 4B5E08EE0E5B680200BEE4E0 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; 4B5E08EF0E5B680200BEE4E0 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; 4B5F253E0DEE9B8F0041E486 /* JackLockedEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */; }; 4B60CE490AAABA31004956AA /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; }; 4B60CE4A0AAABA31004956AA /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; }; 4B6654FC127C350100753A79 /* server_control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6654FB127C350100753A79 /* server_control.cpp */; }; 4B67AB8D14B4B03800B4AA9A /* JackException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B67AB8C14B4B03800B4AA9A /* JackException.cpp */; }; 4B67AB8E14B4B03800B4AA9A /* JackException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B67AB8C14B4B03800B4AA9A /* JackException.cpp */; }; 4B67AB8F14B4B03800B4AA9A /* JackException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B67AB8C14B4B03800B4AA9A /* JackException.cpp */; }; 4B699BAA097D421600A18468 /* Jackdmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */; }; 4B699C03097D421600A18468 /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B699C04097D421600A18468 /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B699C05097D421600A18468 /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; 4B699C06097D421600A18468 /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; 4B699C08097D421600A18468 /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; 4B699C09097D421600A18468 /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; 4B699C0A097D421600A18468 /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; 4B699C0B097D421600A18468 /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; 4B699C0C097D421600A18468 /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; 4B699C0D097D421600A18468 /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; 4B699C0E097D421600A18468 /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; 4B699C0F097D421600A18468 /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; 4B699C10097D421600A18468 /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; 4B699C11097D421600A18468 /* JackLibGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FB0834EFD100C94B91 /* JackLibGlobals.h */; }; 4B699C12097D421600A18468 /* JackLibClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FC0834EFD100C94B91 /* JackLibClient.h */; }; 4B699C13097D421600A18468 /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; 4B699C14097D421600A18468 /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; 4B699C16097D421600A18468 /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4B699C17097D421600A18468 /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B699C18097D421600A18468 /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; 4B699C20097D421600A18468 /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4B699C21097D421600A18468 /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B699C22097D421600A18468 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B699C28097D421600A18468 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B699C29097D421600A18468 /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B699C2B097D421600A18468 /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; 4B699C2C097D421600A18468 /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; 4B699C2D097D421600A18468 /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; 4B699C2E097D421600A18468 /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; 4B699C2F097D421600A18468 /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; 4B699C30097D421600A18468 /* JackLibClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FD0834EFD100C94B91 /* JackLibClient.cpp */; }; 4B699C31097D421600A18468 /* JackLibAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FE0834EFD100C94B91 /* JackLibAPI.cpp */; }; 4B699C32097D421600A18468 /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; 4B699C33097D421600A18468 /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4B699C35097D421600A18468 /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B699C36097D421600A18468 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; 4B699C3D097D421600A18468 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B699C3F097D421600A18468 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B699C40097D421600A18468 /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; 4B699C4F097D421600A18468 /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B699C50097D421600A18468 /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B699C51097D421600A18468 /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; 4B699C52097D421600A18468 /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; 4B699C54097D421600A18468 /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; 4B699C55097D421600A18468 /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; 4B699C56097D421600A18468 /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; 4B699C57097D421600A18468 /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; 4B699C58097D421600A18468 /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; 4B699C59097D421600A18468 /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; 4B699C5A097D421600A18468 /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; 4B699C5B097D421600A18468 /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; 4B699C5C097D421600A18468 /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; 4B699C5D097D421600A18468 /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; 4B699C5E097D421600A18468 /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; 4B699C60097D421600A18468 /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4B699C61097D421600A18468 /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B699C62097D421600A18468 /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; 4B699C68097D421600A18468 /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4B699C69097D421600A18468 /* JackAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2290834F07D00C94B91 /* JackAudioDriver.h */; }; 4B699C6A097D421600A18468 /* JackFreewheelDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B90834EEF100C94B91 /* JackFreewheelDriver.h */; }; 4B699C6B097D421600A18468 /* JackThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1BD0834EEFC00C94B91 /* JackThreadedDriver.h */; }; 4B699C6C097D421600A18468 /* JackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B50834EEE400C94B91 /* JackDriver.h */; }; 4B699C6D097D421600A18468 /* driver_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B3D08C8D21C001CF041 /* driver_interface.h */; }; 4B699C6F097D421600A18468 /* JackDriverLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */; }; 4B699C71097D421600A18468 /* JackEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2130834F02800C94B91 /* JackEngine.h */; }; 4B699C73097D421600A18468 /* JackExternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */; }; 4B699C74097D421600A18468 /* JackServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2220834F05C00C94B91 /* JackServer.h */; }; 4B699C7B097D421600A18468 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B699C7F097D421600A18468 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B699C80097D421600A18468 /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B699C82097D421600A18468 /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; 4B699C83097D421600A18468 /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; 4B699C84097D421600A18468 /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; 4B699C85097D421600A18468 /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; 4B699C86097D421600A18468 /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; 4B699C87097D421600A18468 /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; 4B699C88097D421600A18468 /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4B699C8A097D421600A18468 /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B699C8B097D421600A18468 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; 4B699C8F097D421600A18468 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B699C91097D421600A18468 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B699C92097D421600A18468 /* JackAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D22A0834F07D00C94B91 /* JackAudioDriver.cpp */; }; 4B699C93097D421600A18468 /* JackFreewheelDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BA0834EEF100C94B91 /* JackFreewheelDriver.cpp */; }; 4B699C94097D421600A18468 /* JackThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BE0834EEFC00C94B91 /* JackThreadedDriver.cpp */; }; 4B699C95097D421600A18468 /* JackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */; }; 4B699C96097D421600A18468 /* JackDriverLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */; }; 4B699C97097D421600A18468 /* JackEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2140834F02800C94B91 /* JackEngine.cpp */; }; 4B699C99097D421600A18468 /* JackExternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */; }; 4B699C9A097D421600A18468 /* JackInternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */; }; 4B699C9D097D421600A18468 /* JackServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2210834F05C00C94B91 /* JackServer.cpp */; }; 4B699CB4097D421600A18468 /* metro.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D16B0834EDF000C94B91 /* metro.c */; }; 4B699CC4097D421600A18468 /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1690834EDE600C94B91 /* lsp.c */; }; 4B699CF6097D421600A18468 /* freewheel.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1710834EE0F00C94B91 /* freewheel.c */; }; 4B699D18097D421600A18468 /* testAtomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D23E0834F1C300C94B91 /* testAtomic.cpp */; }; 4B699D2C097D421600A18468 /* testSem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2470834F20600C94B91 /* testSem.cpp */; }; 4B699D42097D421600A18468 /* zombie.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1670834EDD900C94B91 /* zombie.c */; }; 4B699D59097D421600A18468 /* testSynchroServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */; }; 4B699D71097D421600A18468 /* testSynchroClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */; }; 4B699D89097D421700A18468 /* testSynchroServerClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBD13CC08C71EB40079F7FF /* testSynchroServerClient.cpp */; }; 4B699DA8097D421700A18468 /* JackDummyDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */; }; 4B699DAA097D421700A18468 /* JackDummyDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */; }; 4B6B9EF60CD095930051EE5A /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6B9EF70CD095970051EE5A /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73800CC60A7F001AFFD4 /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73810CC60A7F001AFFD4 /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73820CC60A7F001AFFD4 /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73830CC60A80001AFFD4 /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73840CC60A80001AFFD4 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73850CC60A81001AFFD4 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73860CC60A83001AFFD4 /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73870CC60A84001AFFD4 /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73880CC60A84001AFFD4 /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73890CC60A85001AFFD4 /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C738A0CC60A85001AFFD4 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C738B0CC60A86001AFFD4 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6F7AEE0CD0CDBD00F48A9D /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; 4B6FE13A13DDABE000B4B943 /* JackSocketServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B60E703B8D0066E42F /* JackSocketServerNotifyChannel.h */; }; 4B6FE13B13DDABE700B4B943 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; }; 4B6FE13C13DDABF100B4B943 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; }; 4B6FE13D13DDABFA00B4B943 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; }; 4B6FE13E13DDAC0500B4B943 /* JackSocketNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B20E703B8D0066E42F /* JackSocketNotifyChannel.h */; }; 4B6FE13F13DDAC0C00B4B943 /* JackSocketNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B10E703B8D0066E42F /* JackSocketNotifyChannel.cpp */; }; 4B6FE14413DDAC4700B4B943 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; 4B6FE14513DDAC4C00B4B943 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; 4B6FE14D13DDACCC00B4B943 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; 4B6FE14E13DDACD200B4B943 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; 4B6FE15313DDACEF00B4B943 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; 4B6FE15413DDACF300B4B943 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; 4B6FE15B13DDAD3D00B4B943 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; 4B6FE15C13DDAD4600B4B943 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; 4B6FE15D13DDAD4E00B4B943 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; 4B6FE15E13DDAD5300B4B943 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; 4B6FE15F13DDAD5900B4B943 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; 4B6FE16013DDAD5F00B4B943 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; 4B6FE16113DDAD6600B4B943 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; 4B6FE16213DDAD6F00B4B943 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; 4B6FE16313DDAD7700B4B943 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; 4B6FE16413DDAD7F00B4B943 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; 4B6FE16513DDAD8800B4B943 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; 4B6FE16613DDAD8F00B4B943 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; 4B6FE16713DDAD9700B4B943 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; 4B6FE16813DDAD9F00B4B943 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; 4B80D7E80BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B80D7E90BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4B80D7EA0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4B80D7EB0BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B80D7EC0BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4B80D7ED0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4B8692D61371DB4700D2D11B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4B8692F81371DC5200D2D11B /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; 4B8692FA1371DC6300D2D11B /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; 4B8692FB1371DC7100D2D11B /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B8692FD1371DC8A00D2D11B /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B8692FE1371DC9700D2D11B /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; 4B86930D1371DCB000D2D11B /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; 4B8693141371DCCA00D2D11B /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4B8693161371DD0A00D2D11B /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8693151371DD0A00D2D11B /* JackNetAPI.cpp */; }; 4B8693171371DD2400D2D11B /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; 4B8693181371DD2A00D2D11B /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; 4B8693191371DD3B00D2D11B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AD60DC88268001A17F4 /* JackNetTool.cpp */; }; 4B86931A1371DD4400D2D11B /* JackNetTool.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AD70DC88268001A17F4 /* JackNetTool.h */; }; 4B86931B1371DD4C00D2D11B /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4B8693231371DD6000D2D11B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4B8693251371DD7E00D2D11B /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; 4B86932C1371DD9B00D2D11B /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B86934D1371DEBA00D2D11B /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B86934E1371DEBD00D2D11B /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B88D03B11298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D03C11298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D03D11298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D03E11298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D03F11298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04011298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04111298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04211298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04311298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04411298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04511298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B8A38A7117B80D300664E07 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; 4B8A38A8117B80DA00664E07 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; 4B8A38AD117B810A00664E07 /* JackSocketNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B20E703B8D0066E42F /* JackSocketNotifyChannel.h */; }; 4B8A38AE117B811100664E07 /* JackSocketNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B10E703B8D0066E42F /* JackSocketNotifyChannel.cpp */; }; 4B8A38B0117B812500664E07 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; }; 4B8A38B1117B812D00664E07 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; }; 4B8A38B2117B813400664E07 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; }; 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B60E703B8D0066E42F /* JackSocketServerNotifyChannel.h */; }; 4B8A38F0117B827900664E07 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; 4B8A38F1117B827E00664E07 /* JackSocketClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AF0E703B8D0066E42F /* JackSocketClientChannel.cpp */; }; 4B8A38F6117B82AB00664E07 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */; }; 4B8F16F51329161E0002AD73 /* midi_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F16F41329161E0002AD73 /* midi_dump.c */; }; 4B8F16F61329161E0002AD73 /* midi_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F16F41329161E0002AD73 /* midi_dump.c */; }; 4B90669A14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */; }; 4B90669B14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */; }; 4B90669C14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */; }; 4B90669D14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */; }; 4B90669E14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */; }; 4B90669F14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */; }; 4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B93F19C0E87998200E4ECCD /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; 4B93F19D0E87998400E4ECCD /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4B93F19E0E87998400E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B93F1C00E87A35400E4ECCD /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4B93F22B0E87A72500E4ECCD /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4B94334A10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B94334B10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B95BCAE0D913073000F7695 /* control.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B95BCAD0D913073000F7695 /* control.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B97B6381344B3C100794F57 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; 4B97B6391344B3C300794F57 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; 4B97B63A1344B3C700794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; 4B97B63D1344B3EC00794F57 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; 4B97B63E1344B3F100794F57 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; 4B97B6411344B40C00794F57 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; 4B97B6531344B41E00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; 4B97B6541344B42400794F57 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; 4B97B6561344B43600794F57 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; 4B97B6571344B43A00794F57 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; 4B97B6581344B43F00794F57 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; 4B97B6591344B44800794F57 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; 4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; 4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; 4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; 4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; 4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; 4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; 4B97B6601344B48F00794F57 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; 4B97B6611344B49500794F57 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; 4B97B6621344B49C00794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; 4B97B6631344B4A800794F57 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; 4B97B6641344B4AE00794F57 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; 4B97B6651344B4B500794F57 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; 4B97B6671344B4C700794F57 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; 4B97B6691344B4CE00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; 4B97B66E1344B4D500794F57 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; 4B97B66F1344B4DC00794F57 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; 4B97B6701344B4E300794F57 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; 4B97B6711344B4EA00794F57 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; 4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; 4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; 4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; 4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; 4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; 4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; 4B9A25B50DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A25B60DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26010DBF8584006E9FBC /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9A26020DBF8584006E9FBC /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9A26040DBF8584006E9FBC /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (); }; }; 4B9A26050DBF8584006E9FBC /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9A26060DBF8584006E9FBC /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9A26610DBF8ADD006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26640DBF8B14006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26790DBF8B88006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4BA3393610B2E36800190E3B /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4BA3393710B2E36800190E3B /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4BA3393810B2E36800190E3B /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; 4BA3393910B2E36800190E3B /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; 4BA3393A10B2E36800190E3B /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; 4BA3393B10B2E36800190E3B /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; 4BA3393C10B2E36800190E3B /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; 4BA3393D10B2E36800190E3B /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; 4BA3393E10B2E36800190E3B /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; 4BA3393F10B2E36800190E3B /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; 4BA3394010B2E36800190E3B /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; 4BA3394110B2E36800190E3B /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; 4BA3394210B2E36800190E3B /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; 4BA3394310B2E36800190E3B /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; 4BA3394410B2E36800190E3B /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; 4BA3394510B2E36800190E3B /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4BA3394610B2E36800190E3B /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4BA3394710B2E36800190E3B /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; 4BA3394810B2E36800190E3B /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4BA3394910B2E36800190E3B /* JackAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2290834F07D00C94B91 /* JackAudioDriver.h */; }; 4BA3394A10B2E36800190E3B /* JackFreewheelDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B90834EEF100C94B91 /* JackFreewheelDriver.h */; }; 4BA3394B10B2E36800190E3B /* JackThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1BD0834EEFC00C94B91 /* JackThreadedDriver.h */; }; 4BA3394C10B2E36800190E3B /* JackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B50834EEE400C94B91 /* JackDriver.h */; }; 4BA3394D10B2E36800190E3B /* driver_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B3D08C8D21C001CF041 /* driver_interface.h */; }; 4BA3394E10B2E36800190E3B /* JackDriverLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */; }; 4BA3394F10B2E36800190E3B /* JackEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2130834F02800C94B91 /* JackEngine.h */; }; 4BA3395010B2E36800190E3B /* JackExternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */; }; 4BA3395110B2E36800190E3B /* JackServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2220834F05C00C94B91 /* JackServer.h */; }; 4BA3395510B2E36800190E3B /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4BA3395610B2E36800190E3B /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4BA3395710B2E36800190E3B /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; 4BA3395810B2E36800190E3B /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3395910B2E36800190E3B /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3395A10B2E36800190E3B /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3395B10B2E36800190E3B /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3395C10B2E36800190E3B /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3395D10B2E36800190E3B /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3395E10B2E36800190E3B /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3395F10B2E36800190E3B /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3396010B2E36800190E3B /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; 4BA3396110B2E36800190E3B /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4BA3396210B2E36800190E3B /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3396310B2E36800190E3B /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4BA3396410B2E36800190E3B /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; 4BA3396510B2E36800190E3B /* JackNetTool.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AD70DC88268001A17F4 /* JackNetTool.h */; }; 4BA3396610B2E36800190E3B /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BA3396710B2E36800190E3B /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4BA3396810B2E36800190E3B /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; 4BA3396910B2E36800190E3B /* JackControlAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4E9AF90E5F1090000A3278 /* JackControlAPI.h */; }; 4BA3396A10B2E36800190E3B /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4BA3396B10B2E36800190E3B /* JackEngineProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */; }; 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */; }; 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */; }; 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BA3397310B2E36800190E3B /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4BA3397410B2E36800190E3B /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4BA3397510B2E36800190E3B /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; 4BA3397610B2E36800190E3B /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; 4BA3397710B2E36800190E3B /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; 4BA3397810B2E36800190E3B /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; 4BA3397910B2E36800190E3B /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; 4BA3397A10B2E36800190E3B /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; 4BA3397B10B2E36800190E3B /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4BA3397C10B2E36800190E3B /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4BA3397D10B2E36800190E3B /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; 4BA3397E10B2E36800190E3B /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4BA3397F10B2E36800190E3B /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4BA3398010B2E36800190E3B /* JackAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D22A0834F07D00C94B91 /* JackAudioDriver.cpp */; }; 4BA3398110B2E36800190E3B /* JackFreewheelDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BA0834EEF100C94B91 /* JackFreewheelDriver.cpp */; }; 4BA3398210B2E36800190E3B /* JackThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BE0834EEFC00C94B91 /* JackThreadedDriver.cpp */; }; 4BA3398310B2E36800190E3B /* JackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */; }; 4BA3398410B2E36800190E3B /* JackDriverLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */; }; 4BA3398510B2E36800190E3B /* JackEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2140834F02800C94B91 /* JackEngine.cpp */; }; 4BA3398610B2E36800190E3B /* JackExternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */; }; 4BA3398710B2E36800190E3B /* JackInternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */; }; 4BA3398910B2E36800190E3B /* JackServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2210834F05C00C94B91 /* JackServer.cpp */; }; 4BA3398E10B2E36800190E3B /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4BA3398F10B2E36800190E3B /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; 4BA3399010B2E36800190E3B /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; 4BA3399110B2E36800190E3B /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4BA3399210B2E36800190E3B /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; 4BA3399310B2E36800190E3B /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; 4BA3399410B2E36800190E3B /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4BA3399510B2E36800190E3B /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4BA3399610B2E36800190E3B /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; 4BA3399710B2E36800190E3B /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; 4BA3399810B2E36800190E3B /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; 4BA3399910B2E36800190E3B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AD60DC88268001A17F4 /* JackNetTool.cpp */; }; 4BA3399A10B2E36800190E3B /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4BA3399B10B2E36800190E3B /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4BA3399C10B2E36800190E3B /* JackRestartThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */; }; 4BA3399D10B2E36800190E3B /* JackControlAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */; }; 4BA3399E10B2E36800190E3B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4BA3399F10B2E36800190E3B /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BA339A010B2E36800190E3B /* JackEngineProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */; }; 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */; }; 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */; }; 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; 4BA339A710B2E36800190E3B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BA4ADB40E87AB2500F26C85 /* JackCoreAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */; }; 4BA4ADB50E87AB2600F26C85 /* JackCoreAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FECC0E725C090020B576 /* JackCoreAudioDriver.h */; }; 4BA692B30CBE4C2D00EAD520 /* ipload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692B20CBE4C2D00EAD520 /* ipload.c */; }; 4BA692D70CBE4CC600EAD520 /* ipunload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692D60CBE4CC600EAD520 /* ipunload.c */; }; 4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; 4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; 4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; 4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; 4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; 4BA7FECA0D8E76650017FF73 /* control.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA7FEC80D8E76650017FF73 /* control.c */; }; 4BAA150314F04FB600402512 /* JackAC3Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAA150114F04FB600402512 /* JackAC3Encoder.cpp */; }; 4BAA150414F04FB600402512 /* JackAC3Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAA150214F04FB600402512 /* JackAC3Encoder.h */; }; 4BAA150514F04FB600402512 /* JackAC3Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAA150114F04FB600402512 /* JackAC3Encoder.cpp */; }; 4BAA150614F04FB600402512 /* JackAC3Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAA150214F04FB600402512 /* JackAC3Encoder.h */; }; 4BAB95B80B9E20B800A0C723 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; 4BAB95B90B9E20B800A0C723 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; 4BAB95BA0B9E20B800A0C723 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; 4BAB95BB0B9E20B800A0C723 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; 4BAB95ED0B9E21A500A0C723 /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; 4BAB95EE0B9E21A500A0C723 /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; 4BB4214B14D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */; }; 4BB4214C14D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4214914D2C0A700A1CAE1 /* JackPosixProcessSync.cpp */; }; 4BB4214D14D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214A14D2C0A700A1CAE1 /* JackPosixProcessSync.h */; }; 4BB4214E14D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */; }; 4BB4214F14D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4214914D2C0A700A1CAE1 /* JackPosixProcessSync.cpp */; }; 4BB4215014D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214A14D2C0A700A1CAE1 /* JackPosixProcessSync.h */; }; 4BB4215114D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */; }; 4BB4215214D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4214914D2C0A700A1CAE1 /* JackPosixProcessSync.cpp */; }; 4BB4215314D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214A14D2C0A700A1CAE1 /* JackPosixProcessSync.h */; }; 4BB4215414D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */; }; 4BB4215514D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4214914D2C0A700A1CAE1 /* JackPosixProcessSync.cpp */; }; 4BB4215614D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214A14D2C0A700A1CAE1 /* JackPosixProcessSync.h */; }; 4BB4215714D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */; }; 4BB4215814D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4214914D2C0A700A1CAE1 /* JackPosixProcessSync.cpp */; }; 4BB4215914D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214A14D2C0A700A1CAE1 /* JackPosixProcessSync.h */; }; 4BB4215A14D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */; }; 4BB4215B14D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4214914D2C0A700A1CAE1 /* JackPosixProcessSync.cpp */; }; 4BB4215C14D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214A14D2C0A700A1CAE1 /* JackPosixProcessSync.h */; }; 4BB9D4B30E2610B300351653 /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4BB9D4B40E2610B400351653 /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4BB9D4E40E26112900351653 /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; 4BBAE4100F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */; }; 4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */; }; 4BBAE4120F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */; }; 4BBAE4130F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */; }; 4BBB00D30E72614F0018AB1B /* JackPortAudioDevices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB00CF0E72614F0018AB1B /* JackPortAudioDevices.cpp */; }; 4BBB00D40E72614F0018AB1B /* JackPortAudioDevices.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBB00D00E72614F0018AB1B /* JackPortAudioDevices.h */; }; 4BBB00D50E72614F0018AB1B /* JackPortAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB00D10E72614F0018AB1B /* JackPortAudioDriver.cpp */; }; 4BBB00D60E72614F0018AB1B /* JackPortAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBB00D20E72614F0018AB1B /* JackPortAudioDriver.h */; }; 4BBC93BA0DF9736C002DF220 /* JackWaitThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */; }; 4BBC93BB0DF9736C002DF220 /* JackWaitThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */; }; 4BC216850A444BAD00BDA09F /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; 4BC216890A444BDE00BDA09F /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; 4BC2168E0A444BED00BDA09F /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; 4BC2CA55113C6C930076717C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; 4BC2CA56113C6C940076717C /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; 4BC2CA57113C6C9B0076717C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4BC2CA58113C6C9C0076717C /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BC2CA59113C6CB60076717C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; 4BC2CA5A113C6CB80076717C /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; 4BC2CA5B113C6CBE0076717C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4BC2CA5C113C6CC00076717C /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BC2CA5D113C6CC90076717C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; 4BC2CA5E113C6CCA0076717C /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; 4BC2CA5F113C6CD10076717C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BC3B6A40E703B2E0066E42F /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4BC3B6A50E703B2E0066E42F /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4BC3B6A60E703B2E0066E42F /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4BC3B6A70E703B2E0066E42F /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4BCC87960D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87970D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87980D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87990D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BD4B4D809BACD9600750C0F /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4BD4B4D909BACD9600750C0F /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4BD6240D0CBCF16600DE782F /* inprocess.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BD6240C0CBCF16600DE782F /* inprocess.c */; }; 4BDCDB951001FB9C00B15929 /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; 4BDCDB971001FB9C00B15929 /* JackCoreMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */; }; 4BDCDBB91001FCC000B15929 /* JackNetDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222ADD0DC882A5001A17F4 /* JackNetDriver.h */; }; 4BDCDBBD1001FCC000B15929 /* JackNetDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222ADC0DC882A5001A17F4 /* JackNetDriver.cpp */; }; 4BDCDBD11001FD0100B15929 /* JackWaitThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */; }; 4BDCDBD21001FD0200B15929 /* JackWaitThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */; }; 4BDCDBD91001FD2D00B15929 /* JackNetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AEC0DC883B3001A17F4 /* JackNetManager.h */; }; 4BDCDBDE1001FD2D00B15929 /* JackNetManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AEB0DC883B3001A17F4 /* JackNetManager.cpp */; }; 4BDCDBEE1001FD7300B15929 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; 4BDCDBEF1001FD7300B15929 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; 4BDCDBF11001FD7300B15929 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4BDCDBF21001FD7300B15929 /* JackCoreAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FED00E725C320020B576 /* JackCoreAudioAdapter.h */; }; 4BDCDBF41001FD7300B15929 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; 4BDCDBF51001FD7300B15929 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; 4BDCDBF61001FD7300B15929 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4BDCDBF71001FD7300B15929 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; 4BDCDBF81001FD7300B15929 /* JackAudioAdapterFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4BAB00E3480AB00403CDF /* JackAudioAdapterFactory.cpp */; }; 4BDCDBF91001FD7300B15929 /* JackCoreAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5FECF0E725C320020B576 /* JackCoreAudioAdapter.cpp */; }; 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BDCDC111001FDE300B15929 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; 4BDCDC131001FDE300B15929 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4BDCDC141001FDE300B15929 /* JackNetAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */; }; 4BDCDC161001FDE300B15929 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; 4BDCDC191001FDE300B15929 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; 4BDCDC1A1001FDE300B15929 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4BDCDC1B1001FDE300B15929 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; 4BDCDC1C1001FDE300B15929 /* JackNetAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */; }; 4BDCDC1E1001FDE300B15929 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; 4BE3225A0CC611EF00AFA640 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BE3225B0CC611F500AFA640 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BE4CC010CDA153400CCF5BB /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; 4BE4CC020CDA153500CCF5BB /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; 4BE4CC030CDA153500CCF5BB /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; 4BE4CC040CDA153500CCF5BB /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; 4BE5FECD0E725C090020B576 /* JackCoreAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */; }; 4BE5FECE0E725C090020B576 /* JackCoreAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FECC0E725C090020B576 /* JackCoreAudioDriver.h */; }; 4BE5FED10E725C320020B576 /* JackCoreAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5FECF0E725C320020B576 /* JackCoreAudioAdapter.cpp */; }; 4BE5FED20E725C320020B576 /* JackCoreAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FED00E725C320020B576 /* JackCoreAudioAdapter.h */; }; 4BE6C6AD0A3E0A65005A203A /* test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6C6AC0A3E0A65005A203A /* test.cpp */; }; 4BF1007C15135D8200B88F80 /* JackPosixMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */; }; 4BF1007D15135D8800B88F80 /* JackPosixMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */; }; 4BF2841A0F31B4BC00B05BE3 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; 4BF2841B0F31B4BC00B05BE3 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BF3391A0F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; 4BF3391B0F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */; }; 4BF339210F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */; }; 4BF339220F8B873E0080FB5B /* JackMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */; }; 4BF339230F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */; }; 4BF339240F8B873E0080FB5B /* JackMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */; }; 4BF4BAB10E3480AB00403CDF /* JackAudioAdapterFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4BAB00E3480AB00403CDF /* JackAudioAdapterFactory.cpp */; }; 4BF520530CB8D0E80037470E /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4BF520540CB8D0E80037470E /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4BF520590CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (); }; }; 4BF5205A0CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (); }; }; 4BF5FBBC0E878B9C003D2374 /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; 4BF5FBCA0E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BF5FBCB0E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BFA5E9F0DEC4DD900FA4CDB /* testMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */; }; 4BFA82850DF6A9E40087B4E1 /* evmon.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363E200DEB0401001F72D9 /* evmon.c */; }; 4BFA82980DF6A9E40087B4E1 /* bufsize.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363E710DEB0808001F72D9 /* bufsize.c */; }; 4BFA82A40DF6A9E40087B4E1 /* capture_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363EED0DEB094B001F72D9 /* capture_client.c */; }; 4BFA82B00DF6A9E40087B4E1 /* monitor_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F220DEB0AB0001F72D9 /* monitor_client.c */; }; 4BFA82BC0DF6A9E40087B4E1 /* showtime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F3D0DEB0C31001F72D9 /* showtime.c */; }; 4BFA82C80DF6A9E40087B4E1 /* impulse_grabber.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */; }; BA047C760E14E79D0041F3B6 /* JackNetSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = BA047C710E14E7540041F3B6 /* JackNetSocket.h */; }; BA222AD80DC88268001A17F4 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AD60DC88268001A17F4 /* JackNetTool.cpp */; }; BA222AD90DC88269001A17F4 /* JackNetTool.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AD70DC88268001A17F4 /* JackNetTool.h */; }; BA222ADA0DC88269001A17F4 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AD60DC88268001A17F4 /* JackNetTool.cpp */; }; BA222ADB0DC88269001A17F4 /* JackNetTool.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AD70DC88268001A17F4 /* JackNetTool.h */; }; BA222ADE0DC882A5001A17F4 /* JackNetDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222ADC0DC882A5001A17F4 /* JackNetDriver.cpp */; }; BA222ADF0DC882A5001A17F4 /* JackNetDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222ADD0DC882A5001A17F4 /* JackNetDriver.h */; }; BA222AED0DC883B3001A17F4 /* JackNetManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AEB0DC883B3001A17F4 /* JackNetManager.cpp */; }; BA222AEE0DC883B3001A17F4 /* JackNetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AEC0DC883B3001A17F4 /* JackNetManager.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 4B0A28F30D520D11002EFF74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B0A28DC0D52073D002EFF74; remoteInfo = jack_thread_wait; }; 4B0A292F0D5210C4002EFF74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B0A29230D52108E002EFF74; remoteInfo = "jack_thread_wait 64 bits"; }; 4B19B32B0E23636E00DD4A82 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B19B2F60E23620F00DD4A82; remoteInfo = audioadapter; }; 4B20220B133A9C370019E213 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B2021DC133A9BA40019E213; remoteInfo = "jack_midi_latency 64 bits"; }; 4B224B330E65BA330066BE5B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B5E08BF0E5B66EE00BEE4E0; remoteInfo = netadapter; }; 4B3224E610A3157900838A8E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B3224D710A3156800838A8E; remoteInfo = "jack_netone Universal"; }; 4B32258A10A31A9000838A8E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B32255710A3187800838A8E; remoteInfo = "jack_netsource Universal"; }; 4B32258C10A31A9D00838A8E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B3224D710A3156800838A8E; remoteInfo = "jack_netone Universal"; }; 4B32258E10A31AB400838A8E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B32257110A3190C00838A8E; remoteInfo = "jack_netsource 64 bits"; }; 4B32259010A31ABA00838A8E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B32251D10A316B200838A8E; remoteInfo = "jack_netone 64 bits"; }; 4B35C5540D4731D2000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699D03097D421600A18468; remoteInfo = "jack_external_metro Universal"; }; 4B35C67D0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C41B0D4731D1000DE7AE; remoteInfo = "jackdmp framework 64bits"; }; 4B35C67F0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C4270D4731D1000DE7AE; remoteInfo = "Jackmp.framework 64 bits"; }; 4B35C6810D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C4850D4731D1000DE7AE; remoteInfo = "Jackdmp.framework 64 bits"; }; 4B35C6850D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C50A0D4731D1000DE7AE; remoteInfo = "jack_midiseq 64 bits"; }; 4B35C6870D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5160D4731D1000DE7AE; remoteInfo = "jack_midisine 64 bits"; }; 4B35C6890D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5220D4731D1000DE7AE; remoteInfo = "jack_metro 64 bits"; }; 4B35C68B0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C52E0D4731D1000DE7AE; remoteInfo = "jack_lsp 64 bits"; }; 4B35C68D0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C53A0D4731D1000DE7AE; remoteInfo = "jack_connect 64 bits"; }; 4B35C68F0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5460D4731D1000DE7AE; remoteInfo = "jack_disconnect 64 bits"; }; 4B35C6910D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5520D4731D2000DE7AE; remoteInfo = "jack_freewheel 64 bits"; }; 4B35C6930D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5600D4731D2000DE7AE; remoteInfo = "jdelay 64 bits"; }; 4B35C6950D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C56C0D4731D2000DE7AE; remoteInfo = "jack_external_metro 64 bits"; }; 4B35C69B0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C59C0D4731D2000DE7AE; remoteInfo = "zombie 64 bits"; }; 4B35C69D0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5A80D4731D2000DE7AE; remoteInfo = "jack_test 64 bits"; }; 4B35C69F0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5B40D4731D2000DE7AE; remoteInfo = "jack_cpu 64 bits"; }; 4B35C6A10D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5C00D4731D2000DE7AE; remoteInfo = "jack_load 64 bits"; }; 4B35C6A30D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C5CC0D4731D2000DE7AE; remoteInfo = "jack_unload 64 bits"; }; 4B35C6AB0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C6140D4731D2000DE7AE; remoteInfo = "jack_coreaudio 64 bits"; }; 4B35C6AF0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C62A0D4731D2000DE7AE; remoteInfo = "jack_dummy 64 bits"; }; 4B35C6B10D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C6350D4731D3000DE7AE; remoteInfo = "inprocess 64 bits"; }; 4B363DE40DEB037F001F72D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B363DCE0DEB02F6001F72D9; remoteInfo = "jack_alias Universal"; }; 4B363E740DEB0838001F72D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B363E100DEB03C5001F72D9; remoteInfo = "jack_evmon Universal"; }; 4B363E760DEB0838001F72D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B363E440DEB0775001F72D9; remoteInfo = "jack_bufsize Universal"; }; 4B363F240DEB0ABE001F72D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B363F140DEB0A6A001F72D9; remoteInfo = "jack_monitor_client Universal"; }; 4B363F520DEB0CFE001F72D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B363F2B0DEB0BD1001F72D9; remoteInfo = "jack_showtime Universal"; }; 4B363F770DEB0D85001F72D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B363F680DEB0D4E001F72D9; remoteInfo = "jack_impulse_grabber Universal"; }; 4B38120013269CB600C61B14 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B3811551326878E00C61B14; remoteInfo = "jack_latent_client Universal"; }; 4B38120213269CCB00C61B14 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B38118D1326884E00C61B14; remoteInfo = "jack_latent_client 64 bits"; }; 4B43A8CC1014607100E52943 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B43A8B010145F6F00E52943; remoteInfo = "jack_loopback Universal"; }; 4B43A8E81014618D00E52943 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B43A8DD1014615800E52943; remoteInfo = "jack_loopback 64 bits"; }; 4B5A1BCE0CD1CCC80005BF74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B5A1BB10CD1CB9E0005BF74; remoteInfo = jack_midiseq; }; 4B5A1BE10CD1CD730005BF74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B5A1BD00CD1CCE10005BF74; remoteInfo = jack_midisine; }; 4B66550D127C356E00753A79 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B6654ED127C34AE00753A79; remoteInfo = "jack_server_control 64 bits"; }; 4B699DB3097D421700A18468 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699C4C097D421600A18468; remoteInfo = "Jackdmp.framework Universal"; }; 4B699DB5097D421700A18468 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699C00097D421600A18468; remoteInfo = "Jackmp.framework Universal"; }; 4B699DB7097D421700A18468 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699BA7097D421600A18468; remoteInfo = "jackdmp framework Universal"; }; 4B699DB9097D421700A18468 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699D97097D421700A18468; remoteInfo = "jack_coreaudio Universal"; }; 4B699DBB097D421700A18468 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699DA6097D421700A18468; remoteInfo = "jack_dummy Universal"; }; 4B699DBF097D421700A18468 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699D03097D421600A18468; remoteInfo = "jack_external_metro Universal"; }; 4B8F16F9132916910002AD73 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B8F16DB13290DC80002AD73; remoteInfo = "jack_midi_dump Universal"; }; 4B8F16FB1329169F0002AD73 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B8F16E813290E0E0002AD73; remoteInfo = "jack_midi_dump 64 bits"; }; 4BA693E80CBE5BBA00EAD520 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BA692A60CBE4BC700EAD520; remoteInfo = "jack_load Universal"; }; 4BA693EA0CBE5BBA00EAD520 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BA692CA0CBE4C9000EAD520; remoteInfo = "jack_unload Universal"; }; 4BA7FECC0D8E76810017FF73 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BA7FEB90D8E76270017FF73; remoteInfo = "jack_control Universal"; }; 4BAA1A7514CA08FE003269AD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B35C61F0D4731D2000DE7AE; remoteInfo = "jack_portaudio 64 bits"; }; 4BB492A61372A393005F2601 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B8692821371DB4700D2D11B; remoteInfo = "Jacknet.framework 64 bits"; }; 4BD624D20CBCF55700DE782F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BD623ED0CBCF0F000DE782F; remoteInfo = inprocess; }; 4BDCDC2B1002036100B15929 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BDCDB931001FB9C00B15929; remoteInfo = "jack_coremidi 64 bits"; }; 4BDCDC2D1002036100B15929 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BDCDBB71001FCC000B15929; remoteInfo = "jack_net 64 bits"; }; 4BDCDC2F1002036100B15929 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BDCDBD71001FD2D00B15929; remoteInfo = "netmanager 64 bits"; }; 4BDCDC38100203D500B15929 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BDCDBEC1001FD7300B15929; remoteInfo = "audioadapter 64 bits"; }; 4BDCDC3A100203D500B15929 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BDCDC0F1001FDE300B15929; remoteInfo = "netadapter 64 bits"; }; 4BE99D620AD7A19100C59091 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BE99D260AD7A04800C59091; remoteInfo = "jack_cpu Universal"; }; 4BF339270F8B87800080FB5B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BF339020F8B864B0080FB5B; remoteInfo = jack_coremidi; }; 4BFA83310DF6AB540087B4E1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BFA82820DF6A9E40087B4E1; remoteInfo = "jack_evmon 64 bits"; }; 4BFA83330DF6AB540087B4E1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BFA82950DF6A9E40087B4E1; remoteInfo = "jack_bufsize 64 bits"; }; 4BFA83370DF6AB540087B4E1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BFA82AD0DF6A9E40087B4E1; remoteInfo = "jack_monitor_client 64 bits"; }; 4BFA83390DF6AB540087B4E1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BFA82B90DF6A9E40087B4E1; remoteInfo = "jack_showtime 64 bits"; }; 4BFA833B0DF6AB540087B4E1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BFA82C50DF6A9E40087B4E1; remoteInfo = "jack_impulse_grabber 64 bits"; }; 4BFA99430AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699CB1097D421600A18468; remoteInfo = "jack_metro Universal"; }; 4BFA99450AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699CC1097D421600A18468; remoteInfo = "jack_lsp Universal"; }; 4BFA99470AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699CD1097D421600A18468; remoteInfo = "jack_connect Universal"; }; 4BFA99490AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699CE1097D421600A18468; remoteInfo = "jack_disconnect Universal"; }; 4BFA994B0AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699CF1097D421600A18468; remoteInfo = "jack_freewheel Universal"; }; 4BFA994D0AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699D03097D421600A18468; remoteInfo = "jack_external_metro Universal"; }; 4BFA99530AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4B699D3F097D421600A18468; remoteInfo = "zombie Universal"; }; 4BFA99550AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BE6C6910A3E096F005A203A; remoteInfo = "jack_test Universal"; }; 4BFA99AB0AAAF41D009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4BFA99980AAAF3B0009E916C; remoteInfo = "jdelay Universal"; }; BA222AEF0DC883EF001A17F4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = BA222AE00DC882DB001A17F4; remoteInfo = netmanager; }; BA222AF10DC883F3001A17F4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = BA222AC50DC88132001A17F4; remoteInfo = "jack_net Universal"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ringbuffer.c; path = ../common/ringbuffer.c; sourceTree = SOURCE_ROOT; }; 4B05A04D0DF72BC000840F4C /* alsa_driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = alsa_driver.h; path = ../linux/alsa/alsa_driver.h; sourceTree = SOURCE_ROOT; }; 4B05A04E0DF72BC000840F4C /* alsa_midi.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = alsa_midi.h; path = ../linux/alsa/alsa_midi.h; sourceTree = SOURCE_ROOT; }; 4B05A04F0DF72BC000840F4C /* alsa_midi_impl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = alsa_midi_impl.h; path = ../linux/alsa/alsa_midi_impl.h; sourceTree = SOURCE_ROOT; }; 4B05A0500DF72BC000840F4C /* alsa_midi_jackmp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = alsa_midi_jackmp.cpp; path = ../linux/alsa/alsa_midi_jackmp.cpp; sourceTree = SOURCE_ROOT; }; 4B05A0510DF72BC000840F4C /* alsa_rawmidi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = alsa_rawmidi.c; path = ../linux/alsa/alsa_rawmidi.c; sourceTree = SOURCE_ROOT; }; 4B05A0520DF72BC000840F4C /* alsa_seqmidi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = alsa_seqmidi.c; path = ../linux/alsa/alsa_seqmidi.c; sourceTree = SOURCE_ROOT; }; 4B05A0530DF72BC000840F4C /* bitset.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = bitset.h; path = ../linux/alsa/bitset.h; sourceTree = SOURCE_ROOT; }; 4B05A0540DF72BC000840F4C /* generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = generic.h; path = ../linux/alsa/generic.h; sourceTree = SOURCE_ROOT; }; 4B05A0550DF72BC000840F4C /* generic_hw.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = generic_hw.c; path = ../linux/alsa/generic_hw.c; sourceTree = SOURCE_ROOT; }; 4B05A0560DF72BC000840F4C /* hammerfall.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hammerfall.c; path = ../linux/alsa/hammerfall.c; sourceTree = SOURCE_ROOT; }; 4B05A0570DF72BC000840F4C /* hammerfall.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hammerfall.h; path = ../linux/alsa/hammerfall.h; sourceTree = SOURCE_ROOT; }; 4B05A0580DF72BC000840F4C /* hardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hardware.h; path = ../linux/alsa/hardware.h; sourceTree = SOURCE_ROOT; }; 4B05A0590DF72BC000840F4C /* hdsp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hdsp.c; path = ../linux/alsa/hdsp.c; sourceTree = SOURCE_ROOT; }; 4B05A05A0DF72BC000840F4C /* hdsp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hdsp.h; path = ../linux/alsa/hdsp.h; sourceTree = SOURCE_ROOT; }; 4B05A05B0DF72BC000840F4C /* ice1712.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ice1712.c; path = ../linux/alsa/ice1712.c; sourceTree = SOURCE_ROOT; }; 4B05A05C0DF72BC000840F4C /* ice1712.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ice1712.h; path = ../linux/alsa/ice1712.h; sourceTree = SOURCE_ROOT; }; 4B05A05D0DF72BC000840F4C /* JackAlsaDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackAlsaDriver.cpp; path = ../linux/alsa/JackAlsaDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B05A05E0DF72BC000840F4C /* JackAlsaDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackAlsaDriver.h; path = ../linux/alsa/JackAlsaDriver.h; sourceTree = SOURCE_ROOT; }; 4B05A05F0DF72BC000840F4C /* jslist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jslist.h; path = ../linux/alsa/jslist.h; sourceTree = SOURCE_ROOT; }; 4B05A0620DF72BC000840F4C /* midi_pack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = midi_pack.h; path = ../linux/alsa/midi_pack.h; sourceTree = SOURCE_ROOT; }; 4B05A0630DF72BC000840F4C /* midi_unpack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = midi_unpack.h; path = ../linux/alsa/midi_unpack.h; sourceTree = SOURCE_ROOT; }; 4B05A0640DF72BC000840F4C /* usx2y.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = usx2y.c; path = ../linux/alsa/usx2y.c; sourceTree = SOURCE_ROOT; }; 4B05A0650DF72BC000840F4C /* usx2y.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = usx2y.h; path = ../linux/alsa/usx2y.h; sourceTree = SOURCE_ROOT; }; 4B05A07D0DF72BC000840F4C /* driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = driver.h; path = ../linux/driver.h; sourceTree = SOURCE_ROOT; }; 4B05A0830DF72BC000840F4C /* freebob_driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = freebob_driver.h; path = ../linux/freebob/freebob_driver.h; sourceTree = SOURCE_ROOT; }; 4B05A0840DF72BC000840F4C /* JackFreebobDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFreebobDriver.cpp; path = ../linux/freebob/JackFreebobDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B05A0850DF72BC000840F4C /* JackFreebobDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFreebobDriver.h; path = ../linux/freebob/JackFreebobDriver.h; sourceTree = SOURCE_ROOT; }; 4B0A28E60D52073D002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; 4B0A28EC0D520852002EFF74 /* tw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tw.c; path = "../example-clients/tw.c"; sourceTree = SOURCE_ROOT; }; 4B0A292D0D52108E002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGenericClientChannel.cpp; path = ../common/JackGenericClientChannel.cpp; sourceTree = SOURCE_ROOT; }; 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackGenericClientChannel.h; path = ../common/JackGenericClientChannel.h; sourceTree = SOURCE_ROOT; }; 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiAsyncQueue.cpp; path = ../common/JackMidiAsyncQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B193932133F311400547810 /* JackMidiAsyncQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiAsyncQueue.h; path = ../common/JackMidiAsyncQueue.h; sourceTree = SOURCE_ROOT; }; 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiAsyncWaitQueue.cpp; path = ../common/JackMidiAsyncWaitQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiAsyncWaitQueue.h; path = ../common/JackMidiAsyncWaitQueue.h; sourceTree = SOURCE_ROOT; }; 4B193945133F315200547810 /* JackMidiReadQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiReadQueue.cpp; path = ../common/JackMidiReadQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B193946133F315200547810 /* JackMidiReadQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiReadQueue.h; path = ../common/JackMidiReadQueue.h; sourceTree = SOURCE_ROOT; }; 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiBufferReadQueue.cpp; path = ../common/JackMidiBufferReadQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiBufferReadQueue.h; path = ../common/JackMidiBufferReadQueue.h; sourceTree = SOURCE_ROOT; }; 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiBufferWriteQueue.cpp; path = ../common/JackMidiBufferWriteQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiBufferWriteQueue.h; path = ../common/JackMidiBufferWriteQueue.h; sourceTree = SOURCE_ROOT; }; 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiReceiveQueue.cpp; path = ../common/JackMidiReceiveQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiReceiveQueue.h; path = ../common/JackMidiReceiveQueue.h; sourceTree = SOURCE_ROOT; }; 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiSendQueue.cpp; path = ../common/JackMidiSendQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B193976133F31CB00547810 /* JackMidiSendQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiSendQueue.h; path = ../common/JackMidiSendQueue.h; sourceTree = SOURCE_ROOT; }; 4B193977133F31CB00547810 /* JackMidiUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiUtil.cpp; path = ../common/JackMidiUtil.cpp; sourceTree = SOURCE_ROOT; }; 4B193978133F31CB00547810 /* JackMidiUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiUtil.h; path = ../common/JackMidiUtil.h; sourceTree = SOURCE_ROOT; }; 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiWriteQueue.cpp; path = ../common/JackMidiWriteQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiWriteQueue.h; path = ../common/JackMidiWriteQueue.h; sourceTree = SOURCE_ROOT; }; 4B193990133F321500547810 /* JackFilters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFilters.h; path = ../common/JackFilters.h; sourceTree = SOURCE_ROOT; }; 4B19B3000E23620F00DD4A82 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapter.cpp; path = ../common/JackAudioAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapter.h; path = ../common/JackAudioAdapter.h; sourceTree = SOURCE_ROOT; }; 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; 4B19B30C0E2362E700DD4A82 /* JackException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackException.h; path = ../common/JackException.h; sourceTree = SOURCE_ROOT; }; 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackLibSampleRateResampler.cpp; path = ../common/JackLibSampleRateResampler.cpp; sourceTree = SOURCE_ROOT; }; 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLibSampleRateResampler.h; path = ../common/JackLibSampleRateResampler.h; sourceTree = SOURCE_ROOT; }; 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; 4B2021E6133A9BA40019E213 /* jack_midi_latency_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_latency_test; sourceTree = BUILT_PRODUCTS_DIR; }; 4B202209133A9C1C0019E213 /* midi_latency_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midi_latency_test.c; path = "../example-clients/midi_latency_test.c"; sourceTree = SOURCE_ROOT; }; 4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackTimedDriver.cpp; path = ../common/JackTimedDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackTimedDriver.h; path = ../common/JackTimedDriver.h; sourceTree = SOURCE_ROOT; }; 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4B3224E510A3156800838A8E /* jack_netone.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_netone.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetOneDriver.cpp; path = ../common/JackNetOneDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B3224E910A315B100838A8E /* JackNetOneDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetOneDriver.h; path = ../common/JackNetOneDriver.h; sourceTree = SOURCE_ROOT; }; 4B3224EC10A315C400838A8E /* netjack_packet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netjack_packet.c; path = ../common/netjack_packet.c; sourceTree = SOURCE_ROOT; }; 4B3224ED10A315C400838A8E /* netjack_packet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netjack_packet.h; path = ../common/netjack_packet.h; sourceTree = SOURCE_ROOT; }; 4B3224EE10A315C400838A8E /* netjack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netjack.c; path = ../common/netjack.c; sourceTree = SOURCE_ROOT; }; 4B3224EF10A315C400838A8E /* netjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netjack.h; path = ../common/netjack.h; sourceTree = SOURCE_ROOT; }; 4B32252B10A316B200838A8E /* jack_netone.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_netone.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B32256110A3187800838A8E /* jack_netsource */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_netsource; sourceTree = BUILT_PRODUCTS_DIR; }; 4B32256310A318E300838A8E /* netsource.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netsource.c; path = "../example-clients/netsource.c"; sourceTree = SOURCE_ROOT; }; 4B32257B10A3190C00838A8E /* jack_netsource */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_netsource; sourceTree = BUILT_PRODUCTS_DIR; }; 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPosixMutex.cpp; path = ../posix/JackPosixMutex.cpp; sourceTree = SOURCE_ROOT; }; 4B349826133A6AF500D130AB /* JackALSARawMidiDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiDriver.cpp; path = ../linux/alsarawmidi/JackALSARawMidiDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B349827133A6AF500D130AB /* JackALSARawMidiDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiDriver.h; path = ../linux/alsarawmidi/JackALSARawMidiDriver.h; sourceTree = SOURCE_ROOT; }; 4B349828133A6AF500D130AB /* JackALSARawMidiInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiInputPort.cpp; path = ../linux/alsarawmidi/JackALSARawMidiInputPort.cpp; sourceTree = SOURCE_ROOT; }; 4B349829133A6AF500D130AB /* JackALSARawMidiInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiInputPort.h; path = ../linux/alsarawmidi/JackALSARawMidiInputPort.h; sourceTree = SOURCE_ROOT; }; 4B34982A133A6AF500D130AB /* JackALSARawMidiOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiOutputPort.cpp; path = ../linux/alsarawmidi/JackALSARawMidiOutputPort.cpp; sourceTree = SOURCE_ROOT; }; 4B34982B133A6AF500D130AB /* JackALSARawMidiOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiOutputPort.h; path = ../linux/alsarawmidi/JackALSARawMidiOutputPort.h; sourceTree = SOURCE_ROOT; }; 4B34982C133A6AF500D130AB /* JackALSARawMidiPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiPort.cpp; path = ../linux/alsarawmidi/JackALSARawMidiPort.cpp; sourceTree = SOURCE_ROOT; }; 4B34982D133A6AF500D130AB /* JackALSARawMidiPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiPort.h; path = ../linux/alsarawmidi/JackALSARawMidiPort.h; sourceTree = SOURCE_ROOT; }; 4B34982E133A6AF500D130AB /* JackALSARawMidiReceiveQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiReceiveQueue.cpp; path = ../linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B34982F133A6AF500D130AB /* JackALSARawMidiReceiveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiReceiveQueue.h; path = ../linux/alsarawmidi/JackALSARawMidiReceiveQueue.h; sourceTree = SOURCE_ROOT; }; 4B349830133A6AF500D130AB /* JackALSARawMidiSendQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiSendQueue.cpp; path = ../linux/alsarawmidi/JackALSARawMidiSendQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B349831133A6AF500D130AB /* JackALSARawMidiSendQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiSendQueue.h; path = ../linux/alsarawmidi/JackALSARawMidiSendQueue.h; sourceTree = SOURCE_ROOT; }; 4B349838133A6B6F00D130AB /* ffado_driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ffado_driver.h; path = ../linux/firewire/ffado_driver.h; sourceTree = SOURCE_ROOT; }; 4B349839133A6B6F00D130AB /* JackFFADODriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADODriver.cpp; path = ../linux/firewire/JackFFADODriver.cpp; sourceTree = SOURCE_ROOT; }; 4B34983A133A6B6F00D130AB /* JackFFADODriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADODriver.h; path = ../linux/firewire/JackFFADODriver.h; sourceTree = SOURCE_ROOT; }; 4B34983B133A6B6F00D130AB /* JackFFADOMidiInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADOMidiInputPort.cpp; path = ../linux/firewire/JackFFADOMidiInputPort.cpp; sourceTree = SOURCE_ROOT; }; 4B34983C133A6B6F00D130AB /* JackFFADOMidiInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADOMidiInputPort.h; path = ../linux/firewire/JackFFADOMidiInputPort.h; sourceTree = SOURCE_ROOT; }; 4B34983D133A6B6F00D130AB /* JackFFADOMidiOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADOMidiOutputPort.cpp; path = ../linux/firewire/JackFFADOMidiOutputPort.cpp; sourceTree = SOURCE_ROOT; }; 4B34983E133A6B6F00D130AB /* JackFFADOMidiOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADOMidiOutputPort.h; path = ../linux/firewire/JackFFADOMidiOutputPort.h; sourceTree = SOURCE_ROOT; }; 4B34983F133A6B6F00D130AB /* JackFFADOMidiReceiveQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADOMidiReceiveQueue.cpp; path = ../linux/firewire/JackFFADOMidiReceiveQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B349840133A6B6F00D130AB /* JackFFADOMidiReceiveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADOMidiReceiveQueue.h; path = ../linux/firewire/JackFFADOMidiReceiveQueue.h; sourceTree = SOURCE_ROOT; }; 4B349841133A6B6F00D130AB /* JackFFADOMidiSendQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADOMidiSendQueue.cpp; path = ../linux/firewire/JackFFADOMidiSendQueue.cpp; sourceTree = SOURCE_ROOT; }; 4B349842133A6B6F00D130AB /* JackFFADOMidiSendQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADOMidiSendQueue.h; path = ../linux/firewire/JackFFADOMidiSendQueue.h; sourceTree = SOURCE_ROOT; }; 4B35C4250D4731D1000DE7AE /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4830D4731D1000DE7AE /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5140D4731D1000DE7AE /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5200D4731D1000DE7AE /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C52C0D4731D1000DE7AE /* jack_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_metro; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5380D4731D1000DE7AE /* jack_lsp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_lsp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5440D4731D1000DE7AE /* jack_connect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_connect; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5500D4731D1000DE7AE /* jack_disconnect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_disconnect; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C55E0D4731D2000DE7AE /* jack_freewheel */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_freewheel; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C56A0D4731D2000DE7AE /* jack_iodelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_iodelay; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5760D4731D2000DE7AE /* jack_external_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_external_metro; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5860D4731D2000DE7AE /* testAtomic */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testAtomic; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C59A0D4731D2000DE7AE /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5A60D4731D2000DE7AE /* zombie */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = zombie; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5B20D4731D2000DE7AE /* jack_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_test; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5BE0D4731D2000DE7AE /* jack_cpu */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_cpu; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5CA0D4731D2000DE7AE /* jack_load */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_load; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5D60D4731D2000DE7AE /* jack_unload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_unload; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5EA0D4731D2000DE7AE /* synchroServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = synchroServer; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5FE0D4731D2000DE7AE /* synchroClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = synchroClient; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C6120D4731D2000DE7AE /* synchroServerClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = synchroServerClient; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C61E0D4731D2000DE7AE /* jack_coreaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_coreaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C6290D4731D2000DE7AE /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C6340D4731D2000DE7AE /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C63E0D4731D3000DE7AE /* inprocess.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = inprocess.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363DD80DEB02F6001F72D9 /* jack_alias */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_alias; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363DDE0DEB034E001F72D9 /* alias.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = alias.c; path = "../example-clients/alias.c"; sourceTree = SOURCE_ROOT; }; 4B363E1A0DEB03C5001F72D9 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363E200DEB0401001F72D9 /* evmon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = evmon.c; path = "../example-clients/evmon.c"; sourceTree = SOURCE_ROOT; }; 4B363E4E0DEB0775001F72D9 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363E710DEB0808001F72D9 /* bufsize.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bufsize.c; path = "../example-clients/bufsize.c"; sourceTree = SOURCE_ROOT; }; 4B363EE90DEB091C001F72D9 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363EED0DEB094B001F72D9 /* capture_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = capture_client.c; path = "../example-clients/capture_client.c"; sourceTree = SOURCE_ROOT; }; 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F220DEB0AB0001F72D9 /* monitor_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor_client.c; path = "../example-clients/monitor_client.c"; sourceTree = SOURCE_ROOT; }; 4B363F350DEB0BD1001F72D9 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F3D0DEB0C31001F72D9 /* showtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = showtime.c; path = "../example-clients/showtime.c"; sourceTree = SOURCE_ROOT; }; 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = impulse_grabber.c; path = "../example-clients/impulse_grabber.c"; sourceTree = SOURCE_ROOT; }; 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiInputPort.cpp; path = ../../coremidi/JackCoreMidiInputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiInputPort.h; path = ../../coremidi/JackCoreMidiInputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiOutputPort.cpp; path = ../../coremidi/JackCoreMidiOutputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A17133DD7E200237B68 /* JackCoreMidiOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiOutputPort.h; path = ../../coremidi/JackCoreMidiOutputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A18133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiPhysicalInputPort.cpp; path = ../../coremidi/JackCoreMidiPhysicalInputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A19133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiPhysicalInputPort.h; path = ../../coremidi/JackCoreMidiPhysicalInputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A1A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiPhysicalOutputPort.cpp; path = ../../coremidi/JackCoreMidiPhysicalOutputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A1B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiPhysicalOutputPort.h; path = ../../coremidi/JackCoreMidiPhysicalOutputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A1C133DD7E300237B68 /* JackCoreMidiPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiPort.cpp; path = ../../coremidi/JackCoreMidiPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A1D133DD7E300237B68 /* JackCoreMidiPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiPort.h; path = ../../coremidi/JackCoreMidiPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A1E133DD7E300237B68 /* JackCoreMidiUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiUtil.cpp; path = ../../coremidi/JackCoreMidiUtil.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A1F133DD7E300237B68 /* JackCoreMidiUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiUtil.h; path = ../../coremidi/JackCoreMidiUtil.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A20133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiVirtualInputPort.cpp; path = ../../coremidi/JackCoreMidiVirtualInputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A21133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiVirtualInputPort.h; path = ../../coremidi/JackCoreMidiVirtualInputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A22133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiVirtualOutputPort.cpp; path = ../../coremidi/JackCoreMidiVirtualOutputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B370A23133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiVirtualOutputPort.h; path = ../../coremidi/JackCoreMidiVirtualOutputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B38115F1326878E00C61B14 /* jack_latent_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_latent_client; sourceTree = BUILT_PRODUCTS_DIR; }; 4B3811971326884E00C61B14 /* jack_latent_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_latent_client; sourceTree = BUILT_PRODUCTS_DIR; }; 4B3811FA13269C8300C61B14 /* latent_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = latent_client.c; path = "../example-clients/latent_client.c"; sourceTree = SOURCE_ROOT; }; 4B38141F1327AA6800C61B14 /* iodelay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iodelay.cpp; path = ../tests/iodelay.cpp; sourceTree = SOURCE_ROOT; }; 4B3F49070AD8503300491C6E /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = ../tests/cpu.c; sourceTree = SOURCE_ROOT; }; 4B43A8BA10145F6F00E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackLoopbackDriver.cpp; path = ../common/JackLoopbackDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLoopbackDriver.h; path = ../common/JackLoopbackDriver.h; sourceTree = SOURCE_ROOT; }; 4B43A8E71014615800E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B464301076CAC7700E5077C /* Jack-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = SOURCE_ROOT; }; 4B47ACD710B5890100469C67 /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B49D3B314864D41003390F8 /* JackWinMMEDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinMMEDriver.cpp; path = ../windows/winmme/JackWinMMEDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3B414864D41003390F8 /* JackWinMMEDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinMMEDriver.h; path = ../windows/winmme/JackWinMMEDriver.h; sourceTree = SOURCE_ROOT; }; 4B49D3B514864D41003390F8 /* JackWinMMEInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinMMEInputPort.cpp; path = ../windows/winmme/JackWinMMEInputPort.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3B614864D41003390F8 /* JackWinMMEInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinMMEInputPort.h; path = ../windows/winmme/JackWinMMEInputPort.h; sourceTree = SOURCE_ROOT; }; 4B49D3B714864D41003390F8 /* JackWinMMEOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinMMEOutputPort.cpp; path = ../windows/winmme/JackWinMMEOutputPort.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3B814864D41003390F8 /* JackWinMMEOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinMMEOutputPort.h; path = ../windows/winmme/JackWinMMEOutputPort.h; sourceTree = SOURCE_ROOT; }; 4B49D3B914864D41003390F8 /* JackWinMMEPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinMMEPort.cpp; path = ../windows/winmme/JackWinMMEPort.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3BA14864D41003390F8 /* JackWinMMEPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinMMEPort.h; path = ../windows/winmme/JackWinMMEPort.h; sourceTree = SOURCE_ROOT; }; 4B49D3BC14864D49003390F8 /* JackPortAudioAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortAudioAdapter.cpp; path = ../windows/portaudio/JackPortAudioAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3BD14864D49003390F8 /* JackPortAudioAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPortAudioAdapter.h; path = ../windows/portaudio/JackPortAudioAdapter.h; sourceTree = SOURCE_ROOT; }; 4B49D3BE14864D49003390F8 /* JackPortAudioDevices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortAudioDevices.cpp; path = ../windows/portaudio/JackPortAudioDevices.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3BF14864D49003390F8 /* JackPortAudioDevices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPortAudioDevices.h; path = ../windows/portaudio/JackPortAudioDevices.h; sourceTree = SOURCE_ROOT; }; 4B49D3C014864D49003390F8 /* JackPortAudioDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortAudioDriver.cpp; path = ../windows/portaudio/JackPortAudioDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3C114864D49003390F8 /* JackPortAudioDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPortAudioDriver.h; path = ../windows/portaudio/JackPortAudioDriver.h; sourceTree = SOURCE_ROOT; }; 4B49D3C214864D49003390F8 /* pa_asio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pa_asio.h; path = ../windows/portaudio/pa_asio.h; sourceTree = SOURCE_ROOT; }; 4B49D3C314864D49003390F8 /* portaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = portaudio.h; path = ../windows/portaudio/portaudio.h; sourceTree = SOURCE_ROOT; }; 4B49D3C914864DA7003390F8 /* JackLinuxTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = JackLinuxTime.c; path = ../linux/JackLinuxTime.c; sourceTree = SOURCE_ROOT; }; 4B49D3D814864DEC003390F8 /* JackWinThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinThread.cpp; path = ../windows/JackWinThread.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3D914864DEC003390F8 /* JackWinServerLaunch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinServerLaunch.cpp; path = ../windows/JackWinServerLaunch.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3DA14864DEC003390F8 /* JackWinSemaphore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinSemaphore.cpp; path = ../windows/JackWinSemaphore.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3DB14864DEC003390F8 /* JackWinProcessSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinProcessSync.cpp; path = ../windows/JackWinProcessSync.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3DC14864DEC003390F8 /* JackWinNamedPipeServerNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinNamedPipeServerNotifyChannel.cpp; path = ../windows/JackWinNamedPipeServerNotifyChannel.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3DD14864DEC003390F8 /* JackWinNamedPipeServerChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinNamedPipeServerChannel.cpp; path = ../windows/JackWinNamedPipeServerChannel.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3DE14864DEC003390F8 /* JackWinNamedPipeNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinNamedPipeNotifyChannel.cpp; path = ../windows/JackWinNamedPipeNotifyChannel.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3DF14864DEC003390F8 /* JackWinNamedPipeClientChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinNamedPipeClientChannel.cpp; path = ../windows/JackWinNamedPipeClientChannel.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3E014864DED003390F8 /* JackWinNamedPipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinNamedPipe.cpp; path = ../windows/JackWinNamedPipe.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3E114864DED003390F8 /* JackWinEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWinEvent.cpp; path = ../windows/JackWinEvent.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3E214864DED003390F8 /* JackNetWinSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetWinSocket.cpp; path = ../windows/JackNetWinSocket.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3E314864DED003390F8 /* JackMMCSS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMMCSS.cpp; path = ../windows/JackMMCSS.cpp; sourceTree = SOURCE_ROOT; }; 4B49D3E414864DED003390F8 /* JackWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = JackWinTime.c; path = ../windows/JackWinTime.c; sourceTree = SOURCE_ROOT; }; 4B49D3EA14864DED003390F8 /* JackWinThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinThread.h; path = ../windows/JackWinThread.h; sourceTree = SOURCE_ROOT; }; 4B49D3EB14864DED003390F8 /* JackWinSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinSemaphore.h; path = ../windows/JackWinSemaphore.h; sourceTree = SOURCE_ROOT; }; 4B49D3EC14864DED003390F8 /* JackWinProcessSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinProcessSync.h; path = ../windows/JackWinProcessSync.h; sourceTree = SOURCE_ROOT; }; 4B49D3ED14864DED003390F8 /* JackWinNamedPipeServerNotifyChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinNamedPipeServerNotifyChannel.h; path = ../windows/JackWinNamedPipeServerNotifyChannel.h; sourceTree = SOURCE_ROOT; }; 4B49D3EE14864DED003390F8 /* JackWinNamedPipeServerChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinNamedPipeServerChannel.h; path = ../windows/JackWinNamedPipeServerChannel.h; sourceTree = SOURCE_ROOT; }; 4B49D3EF14864DED003390F8 /* JackWinNamedPipeNotifyChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinNamedPipeNotifyChannel.h; path = ../windows/JackWinNamedPipeNotifyChannel.h; sourceTree = SOURCE_ROOT; }; 4B49D3F014864DED003390F8 /* JackWinNamedPipeClientChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinNamedPipeClientChannel.h; path = ../windows/JackWinNamedPipeClientChannel.h; sourceTree = SOURCE_ROOT; }; 4B49D3F114864DED003390F8 /* JackWinNamedPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinNamedPipe.h; path = ../windows/JackWinNamedPipe.h; sourceTree = SOURCE_ROOT; }; 4B49D3F214864DED003390F8 /* JackWinMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinMutex.h; path = ../windows/JackWinMutex.h; sourceTree = SOURCE_ROOT; }; 4B49D3F314864DED003390F8 /* JackWinEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWinEvent.h; path = ../windows/JackWinEvent.h; sourceTree = SOURCE_ROOT; }; 4B49D3F814864DED003390F8 /* JackNetWinSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetWinSocket.h; path = ../windows/JackNetWinSocket.h; sourceTree = SOURCE_ROOT; }; 4B49D3F914864DED003390F8 /* JackMMCSS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMMCSS.h; path = ../windows/JackMMCSS.h; sourceTree = SOURCE_ROOT; }; 4B49D44014865F22003390F8 /* net.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = net.h; path = ../common/jack/net.h; sourceTree = SOURCE_ROOT; }; 4B49D44114865F22003390F8 /* session.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = session.h; path = ../common/jack/session.h; sourceTree = SOURCE_ROOT; }; 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackRestartThreadedDriver.h; path = ../common/JackRestartThreadedDriver.h; sourceTree = SOURCE_ROOT; }; 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackRestartThreadedDriver.cpp; path = ../common/JackRestartThreadedDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackControlAPI.cpp; path = ../common/JackControlAPI.cpp; sourceTree = SOURCE_ROOT; }; 4B4E9AF90E5F1090000A3278 /* JackControlAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackControlAPI.h; path = ../common/JackControlAPI.h; sourceTree = SOURCE_ROOT; }; 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMessageBuffer.cpp; path = ../common/JackMessageBuffer.cpp; sourceTree = SOURCE_ROOT; }; 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMessageBuffer.h; path = ../common/JackMessageBuffer.h; sourceTree = SOURCE_ROOT; }; 4B57F5950D72C27900B4E719 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5A1BBB0CD1CB9E0005BF74 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5A1BBD0CD1CC110005BF74 /* midiseq.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midiseq.c; path = "../example-clients/midiseq.c"; sourceTree = SOURCE_ROOT; }; 4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5A1BDC0CD1CD420005BF74 /* midisine.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midisine.c; path = "../example-clients/midisine.c"; sourceTree = SOURCE_ROOT; }; 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetAdapter.cpp; path = ../common/JackNetAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetAdapter.h; path = ../common/JackNetAdapter.h; sourceTree = SOURCE_ROOT; }; 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLockedEngine.h; path = ../common/JackLockedEngine.h; sourceTree = SOURCE_ROOT; }; 4B60CE480AAABA31004956AA /* connect.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = connect.c; path = "../example-clients/connect.c"; sourceTree = SOURCE_ROOT; }; 4B6654F7127C34AE00753A79 /* jack_server_control */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_server_control; sourceTree = BUILT_PRODUCTS_DIR; }; 4B6654FB127C350100753A79 /* server_control.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = server_control.cpp; path = "../example-clients/server_control.cpp"; sourceTree = SOURCE_ROOT; }; 4B66A8580934964500A89560 /* JackConstants.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackConstants.h; path = ../common/JackConstants.h; sourceTree = SOURCE_ROOT; }; 4B67AB8C14B4B03800B4AA9A /* JackException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackException.cpp; path = ../common/JackException.cpp; sourceTree = SOURCE_ROOT; }; 4B699BB1097D421600A18468 /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699C47097D421600A18468 /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699CAC097D421600A18468 /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699CBB097D421600A18468 /* jack_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_metro; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699CCB097D421600A18468 /* jack_lsp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_lsp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699CDB097D421600A18468 /* jack_connect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_connect; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699CEB097D421600A18468 /* jack_disconnect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_disconnect; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699CFD097D421600A18468 /* jack_freewheel */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_freewheel; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699D0D097D421600A18468 /* jack_external_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_external_metro; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699D21097D421600A18468 /* testAtomic */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testAtomic; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699D39097D421600A18468 /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699D49097D421600A18468 /* zombie */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = zombie; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699D61097D421600A18468 /* synchroServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = synchroServer; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699D79097D421600A18468 /* synchroClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = synchroClient; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699D91097D421700A18468 /* synchroServerClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = synchroServerClient; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699DA1097D421700A18468 /* jack_coreaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_coreaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699DB0097D421700A18468 /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B6B9EF50CD0958B0051EE5A /* midiport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = midiport.h; path = ../common/jack/midiport.h; sourceTree = SOURCE_ROOT; }; 4B6C73790CC60A6D001AFFD4 /* intclient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = intclient.h; path = ../common/jack/intclient.h; sourceTree = SOURCE_ROOT; }; 4B6C737A0CC60A6D001AFFD4 /* jack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jack.h; path = ../common/jack/jack.h; sourceTree = SOURCE_ROOT; }; 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ringbuffer.h; path = ../common/jack/ringbuffer.h; sourceTree = SOURCE_ROOT; }; 4B6C737C0CC60A6D001AFFD4 /* statistics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = statistics.h; path = ../common/jack/statistics.h; sourceTree = SOURCE_ROOT; }; 4B6C737D0CC60A6D001AFFD4 /* thread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = thread.h; path = ../common/jack/thread.h; sourceTree = SOURCE_ROOT; }; 4B6C737E0CC60A6D001AFFD4 /* transport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = transport.h; path = ../common/jack/transport.h; sourceTree = SOURCE_ROOT; }; 4B6C737F0CC60A6D001AFFD4 /* types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../common/jack/types.h; sourceTree = SOURCE_ROOT; }; 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackEngineControl.cpp; path = ../common/JackEngineControl.cpp; sourceTree = SOURCE_ROOT; }; 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetInterface.cpp; path = ../common/JackNetInterface.cpp; sourceTree = SOURCE_ROOT; }; 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetInterface.h; path = ../common/JackNetInterface.h; sourceTree = SOURCE_ROOT; }; 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackMidiPort.h; path = ../common/JackMidiPort.h; sourceTree = SOURCE_ROOT; }; 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiPort.cpp; path = ../common/JackMidiPort.cpp; sourceTree = SOURCE_ROOT; }; 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiAPI.cpp; path = ../common/JackMidiAPI.cpp; sourceTree = SOURCE_ROOT; }; 4B8692DB1371DB4700D2D11B /* Jacknet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jacknet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B8693151371DD0A00D2D11B /* JackNetAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetAPI.cpp; path = ../common/JackNetAPI.cpp; sourceTree = SOURCE_ROOT; }; 4B869B3D08C8D21C001CF041 /* driver_interface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = driver_interface.h; path = ../common/driver_interface.h; sourceTree = SOURCE_ROOT; }; 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDriverLoader.h; path = ../common/JackDriverLoader.h; sourceTree = SOURCE_ROOT; }; 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDriverLoader.cpp; path = ../common/JackDriverLoader.cpp; sourceTree = SOURCE_ROOT; }; 4B88D03911298BEE007A87C1 /* weakjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weakjack.h; path = ../common/jack/weakjack.h; sourceTree = SOURCE_ROOT; }; 4B88D03A11298BEE007A87C1 /* weakmacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weakmacros.h; path = ../common/jack/weakmacros.h; sourceTree = SOURCE_ROOT; }; 4B8F16E513290DC80002AD73 /* jack_midi_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_dump; sourceTree = BUILT_PRODUCTS_DIR; }; 4B8F16F213290E0E0002AD73 /* jack_midi_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_dump; sourceTree = BUILT_PRODUCTS_DIR; }; 4B8F16F41329161E0002AD73 /* midi_dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midi_dump.c; path = "../example-clients/midi_dump.c"; sourceTree = SOURCE_ROOT; }; 4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackRequestDecoder.cpp; path = ../common/JackRequestDecoder.cpp; sourceTree = SOURCE_ROOT; }; 4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackRequestDecoder.h; path = ../common/JackRequestDecoder.h; sourceTree = SOURCE_ROOT; }; 4B90679914BEFB500074CD40 /* JackSolarisTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = JackSolarisTime.c; path = ../solaris/JackSolarisTime.c; sourceTree = SOURCE_ROOT; }; 4B90679A14BEFB5A0074CD40 /* JackBoomerDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackBoomerDriver.cpp; path = ../solaris/oss/JackBoomerDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B90679B14BEFB5A0074CD40 /* JackBoomerDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackBoomerDriver.h; path = ../solaris/oss/JackBoomerDriver.h; sourceTree = SOURCE_ROOT; }; 4B90679C14BEFB5A0074CD40 /* JackOSSAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackOSSAdapter.cpp; path = ../solaris/oss/JackOSSAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B90679D14BEFB5A0074CD40 /* JackOSSAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackOSSAdapter.h; path = ../solaris/oss/JackOSSAdapter.h; sourceTree = SOURCE_ROOT; }; 4B90679E14BEFB5A0074CD40 /* JackOSSDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackOSSDriver.cpp; path = ../solaris/oss/JackOSSDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B90679F14BEFB5A0074CD40 /* JackOSSDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackOSSDriver.h; path = ../solaris/oss/JackOSSDriver.h; sourceTree = SOURCE_ROOT; }; 4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = ""; }; 4B94334910A5E666002A187F /* systemdeps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = systemdeps.h; path = ../common/jack/systemdeps.h; sourceTree = SOURCE_ROOT; }; 4B95BCAD0D913073000F7695 /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = ../common/jack/control.h; sourceTree = SOURCE_ROOT; }; 4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B98AE000931D30C0091932A /* JackDebugClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDebugClient.cpp; path = ../common/JackDebugClient.cpp; sourceTree = SOURCE_ROOT; }; 4B98AE010931D30C0091932A /* JackDebugClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDebugClient.h; path = ../common/JackDebugClient.h; sourceTree = SOURCE_ROOT; }; 4B9A25B30DBF8330006E9FBC /* JackError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackError.cpp; path = ../common/JackError.cpp; sourceTree = SOURCE_ROOT; }; 4B9A26000DBF8584006E9FBC /* jslist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jslist.h; path = ../common/jack/jslist.h; sourceTree = SOURCE_ROOT; }; 4BA2574C132FB49B009F2D3F /* alsa_driver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alsa_driver.c; sourceTree = ""; }; 4BA339AC10B2E36800190E3B /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroClient.cpp; path = ../tests/testSynchroClient.cpp; sourceTree = SOURCE_ROOT; }; 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroServer.cpp; path = ../tests/testSynchroServer.cpp; sourceTree = SOURCE_ROOT; }; 4BA692B00CBE4BC700EAD520 /* jack_load */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_load; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA692B20CBE4C2D00EAD520 /* ipload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipload.c; path = "../example-clients/ipload.c"; sourceTree = SOURCE_ROOT; }; 4BA692D40CBE4C9000EAD520 /* jack_unload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_unload; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA692D60CBE4CC600EAD520 /* ipunload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipunload.c; path = "../example-clients/ipunload.c"; sourceTree = SOURCE_ROOT; }; 4BA7FEC30D8E76270017FF73 /* jack_server_control */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_server_control; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA7FEC80D8E76650017FF73 /* control.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = control.c; path = "../example-clients/control.c"; sourceTree = SOURCE_ROOT; }; 4BAA150114F04FB600402512 /* JackAC3Encoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAC3Encoder.cpp; path = ../common/JackAC3Encoder.cpp; sourceTree = SOURCE_ROOT; }; 4BAA150214F04FB600402512 /* JackAC3Encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAC3Encoder.h; path = ../common/JackAC3Encoder.h; sourceTree = SOURCE_ROOT; }; 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortType.cpp; path = ../common/JackPortType.cpp; sourceTree = SOURCE_ROOT; }; 4BAB95B70B9E20B800A0C723 /* JackPortType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortType.h; path = ../common/JackPortType.h; sourceTree = SOURCE_ROOT; }; 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioPort.cpp; path = ../common/JackAudioPort.cpp; sourceTree = SOURCE_ROOT; }; 4BB371D40C1AD85A0050C1E4 /* JackNotification.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNotification.h; path = ../common/JackNotification.h; sourceTree = SOURCE_ROOT; }; 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPosixMutex.h; path = ../posix/JackPosixMutex.h; sourceTree = SOURCE_ROOT; }; 4BB4214914D2C0A700A1CAE1 /* JackPosixProcessSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPosixProcessSync.cpp; path = ../posix/JackPosixProcessSync.cpp; sourceTree = SOURCE_ROOT; }; 4BB4214A14D2C0A700A1CAE1 /* JackPosixProcessSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPosixProcessSync.h; path = ../posix/JackPosixProcessSync.h; sourceTree = SOURCE_ROOT; }; 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackEngineProfiling.h; path = ../common/JackEngineProfiling.h; sourceTree = SOURCE_ROOT; }; 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackEngineProfiling.cpp; path = ../common/JackEngineProfiling.cpp; sourceTree = SOURCE_ROOT; }; 4BBB00CF0E72614F0018AB1B /* JackPortAudioDevices.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortAudioDevices.cpp; path = ../windows/portaudio/JackPortAudioDevices.cpp; sourceTree = SOURCE_ROOT; }; 4BBB00D00E72614F0018AB1B /* JackPortAudioDevices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortAudioDevices.h; path = ../windows/portaudio/JackPortAudioDevices.h; sourceTree = SOURCE_ROOT; }; 4BBB00D10E72614F0018AB1B /* JackPortAudioDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortAudioDriver.cpp; path = ../windows/portaudio/JackPortAudioDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BBB00D20E72614F0018AB1B /* JackPortAudioDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortAudioDriver.h; path = ../windows/portaudio/JackPortAudioDriver.h; sourceTree = SOURCE_ROOT; }; 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackWaitThreadedDriver.cpp; path = ../common/JackWaitThreadedDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackWaitThreadedDriver.h; path = ../common/JackWaitThreadedDriver.h; sourceTree = SOURCE_ROOT; }; 4BBD13CC08C71EB40079F7FF /* testSynchroServerClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroServerClient.cpp; path = ../tests/testSynchroServerClient.cpp; sourceTree = SOURCE_ROOT; }; 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackServerGlobals.cpp; path = ../common/JackServerGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackServerGlobals.h; path = ../common/JackServerGlobals.h; sourceTree = SOURCE_ROOT; }; 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDummyDriver.cpp; path = ../common/JackDummyDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDummyDriver.h; path = ../common/JackDummyDriver.h; sourceTree = SOURCE_ROOT; }; 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPosixThread.cpp; path = ../posix/JackPosixThread.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPosixThread.h; path = ../posix/JackPosixThread.h; sourceTree = SOURCE_ROOT; }; 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackSocket.cpp; path = ../posix/JackSocket.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackSocket.h; path = ../posix/JackSocket.h; sourceTree = SOURCE_ROOT; }; 4BC3B6AF0E703B8D0066E42F /* JackSocketClientChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackSocketClientChannel.cpp; path = ../posix/JackSocketClientChannel.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackSocketClientChannel.h; path = ../posix/JackSocketClientChannel.h; sourceTree = SOURCE_ROOT; }; 4BC3B6B10E703B8D0066E42F /* JackSocketNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackSocketNotifyChannel.cpp; path = ../posix/JackSocketNotifyChannel.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6B20E703B8D0066E42F /* JackSocketNotifyChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackSocketNotifyChannel.h; path = ../posix/JackSocketNotifyChannel.h; sourceTree = SOURCE_ROOT; }; 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackSocketServerChannel.cpp; path = ../posix/JackSocketServerChannel.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackSocketServerChannel.h; path = ../posix/JackSocketServerChannel.h; sourceTree = SOURCE_ROOT; }; 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackSocketServerNotifyChannel.cpp; path = ../posix/JackSocketServerNotifyChannel.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6B60E703B8D0066E42F /* JackSocketServerNotifyChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackSocketServerNotifyChannel.h; path = ../posix/JackSocketServerNotifyChannel.h; sourceTree = SOURCE_ROOT; }; 4BC3B6B70E703BAA0066E42F /* JackPosixSemaphore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPosixSemaphore.cpp; path = ../posix/JackPosixSemaphore.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6B80E703BAA0066E42F /* JackPosixSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPosixSemaphore.h; path = ../posix/JackPosixSemaphore.h; sourceTree = SOURCE_ROOT; }; 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetUnixSocket.cpp; path = ../posix/JackNetUnixSocket.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetUnixSocket.h; path = ../posix/JackNetUnixSocket.h; sourceTree = SOURCE_ROOT; }; 4BC8326D0DF42C7D00DD1C93 /* JackMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMutex.h; path = ../common/JackMutex.h; sourceTree = SOURCE_ROOT; }; 4BCC87950D57168300A7FEB1 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = /System/Library/Frameworks/Accelerate.framework; sourceTree = ""; }; 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTransportEngine.h; path = ../common/JackTransportEngine.h; sourceTree = SOURCE_ROOT; }; 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackTransportEngine.cpp; path = ../common/JackTransportEngine.cpp; sourceTree = SOURCE_ROOT; }; 4BD561C708EEB910006BBC2A /* JackSynchro.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackSynchro.h; path = ../common/JackSynchro.h; sourceTree = SOURCE_ROOT; }; 4BD623F70CBCF0F000DE782F /* inprocess.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = inprocess.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BD6240C0CBCF16600DE782F /* inprocess.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inprocess.c; path = "../example-clients/inprocess.c"; sourceTree = SOURCE_ROOT; }; 4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_coremidi.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BDCDBC51001FCC000B15929 /* jack_net.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_net.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BDCDBE81001FD2D00B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BDCDBFF1001FD7300B15929 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BDCDC251001FDE300B15929 /* netadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackTools.cpp; path = ../common/JackTools.cpp; sourceTree = SOURCE_ROOT; }; 4BE4CC000CDA153400CCF5BB /* JackTools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTools.h; path = ../common/JackTools.h; sourceTree = SOURCE_ROOT; }; 4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreAudioDriver.cpp; path = coreaudio/JackCoreAudioDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BE5FECC0E725C090020B576 /* JackCoreAudioDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackCoreAudioDriver.h; path = coreaudio/JackCoreAudioDriver.h; sourceTree = SOURCE_ROOT; }; 4BE5FECF0E725C320020B576 /* JackCoreAudioAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreAudioAdapter.cpp; path = coreaudio/JackCoreAudioAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4BE5FED00E725C320020B576 /* JackCoreAudioAdapter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackCoreAudioAdapter.h; path = coreaudio/JackCoreAudioAdapter.h; sourceTree = SOURCE_ROOT; }; 4BE6C6A30A3E096F005A203A /* jack_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_test; sourceTree = BUILT_PRODUCTS_DIR; }; 4BE6C6AC0A3E0A65005A203A /* test.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = test.cpp; path = ../tests/test.cpp; sourceTree = SOURCE_ROOT; }; 4BE99D300AD7A04800C59091 /* jack_cpu */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_cpu; sourceTree = BUILT_PRODUCTS_DIR; }; 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackArgParser.cpp; path = ../common/JackArgParser.cpp; sourceTree = SOURCE_ROOT; }; 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackArgParser.h; path = ../common/JackArgParser.h; sourceTree = SOURCE_ROOT; }; 4BF3390C0F8B864B0080FB5B /* jack_coremidi.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_coremidi.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiDriver.h; path = coremidi/JackCoreMidiDriver.h; sourceTree = SOURCE_ROOT; }; 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiDriver.cpp; path = coremidi/JackCoreMidiDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiDriver.cpp; path = ../common/JackMidiDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiDriver.h; path = ../common/JackMidiDriver.h; sourceTree = SOURCE_ROOT; }; 4BF4BAB00E3480AB00403CDF /* JackAudioAdapterFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterFactory.cpp; path = ../common/JackAudioAdapterFactory.cpp; sourceTree = SOURCE_ROOT; }; 4BF520520CB8D0E80037470E /* timestamps.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = timestamps.c; path = ../common/timestamps.c; sourceTree = SOURCE_ROOT; }; 4BF520580CB8D1010037470E /* timestamps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = timestamps.h; path = ../common/timestamps.h; sourceTree = SOURCE_ROOT; }; 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPosixServerLaunch.cpp; path = ../posix/JackPosixServerLaunch.cpp; sourceTree = SOURCE_ROOT; }; 4BF5FBC80E878D24003D2374 /* JackMachTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = JackMachTime.c; sourceTree = SOURCE_ROOT; }; 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachSemaphore.cpp; sourceTree = SOURCE_ROOT; }; 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachSemaphore.h; sourceTree = SOURCE_ROOT; }; 4BF772FD08B3330F00149912 /* JackAtomic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackAtomic.h; path = ../common/JackAtomic.h; sourceTree = SOURCE_ROOT; }; 4BF8D1670834EDD900C94B91 /* zombie.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = zombie.c; path = "../example-clients/zombie.c"; sourceTree = SOURCE_ROOT; }; 4BF8D1690834EDE600C94B91 /* lsp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lsp.c; path = "..//example-clients/lsp.c"; sourceTree = SOURCE_ROOT; }; 4BF8D16B0834EDF000C94B91 /* metro.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = metro.c; path = "../example-clients/metro.c"; sourceTree = SOURCE_ROOT; }; 4BF8D1710834EE0F00C94B91 /* freewheel.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = freewheel.c; path = "../example-clients/freewheel.c"; sourceTree = SOURCE_ROOT; }; 4BF8D1770834EE4800C94B91 /* JackError.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackError.h; path = ../common/JackError.h; sourceTree = SOURCE_ROOT; }; 4BF8D1830834EE5800C94B91 /* JackTime.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTime.h; path = ../common/JackTime.h; sourceTree = SOURCE_ROOT; }; 4BF8D1870834EE7900C94B91 /* JackShmMem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackShmMem.h; path = ../common/JackShmMem.h; sourceTree = SOURCE_ROOT; }; 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackShmMem.cpp; path = ../common/JackShmMem.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D18F0834EE8400C94B91 /* shm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = shm.h; path = ../common/shm.h; sourceTree = SOURCE_ROOT; }; 4BF8D1900834EE8400C94B91 /* shm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = shm.c; path = ../common/shm.c; sourceTree = SOURCE_ROOT; }; 4BF8D19F0834EE9E00C94B91 /* JackThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackThread.h; path = ../common/JackThread.h; sourceTree = SOURCE_ROOT; }; 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackActivationCount.h; path = ../common/JackActivationCount.h; sourceTree = SOURCE_ROOT; }; 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackActivationCount.cpp; path = ../common/JackActivationCount.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackChannel.h; path = ../common/JackChannel.h; sourceTree = SOURCE_ROOT; }; 4BF8D1B30834EED500C94B91 /* JackInternalClientChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackInternalClientChannel.h; path = ../common/JackInternalClientChannel.h; sourceTree = SOURCE_ROOT; }; 4BF8D1B50834EEE400C94B91 /* JackDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDriver.h; path = ../common/JackDriver.h; sourceTree = SOURCE_ROOT; }; 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDriver.cpp; path = ../common/JackDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1B90834EEF100C94B91 /* JackFreewheelDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFreewheelDriver.h; path = ../common/JackFreewheelDriver.h; sourceTree = SOURCE_ROOT; }; 4BF8D1BA0834EEF100C94B91 /* JackFreewheelDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFreewheelDriver.cpp; path = ../common/JackFreewheelDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1BD0834EEFC00C94B91 /* JackThreadedDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackThreadedDriver.h; path = ../common/JackThreadedDriver.h; sourceTree = SOURCE_ROOT; }; 4BF8D1BE0834EEFC00C94B91 /* JackThreadedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackThreadedDriver.cpp; path = ../common/JackThreadedDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1C10834EF0800C94B91 /* JackAtomicState.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackAtomicState.h; path = ../common/JackAtomicState.h; sourceTree = SOURCE_ROOT; }; 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackConnectionManager.h; path = ../common/JackConnectionManager.h; sourceTree = SOURCE_ROOT; }; 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackConnectionManager.cpp; path = ../common/JackConnectionManager.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackGraphManager.h; path = ../common/JackGraphManager.h; sourceTree = SOURCE_ROOT; }; 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGraphManager.cpp; path = ../common/JackGraphManager.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPort.h; path = ../common/JackPort.h; sourceTree = SOURCE_ROOT; }; 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPort.cpp; path = ../common/JackPort.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackClientInterface.h; path = ../common/JackClientInterface.h; sourceTree = SOURCE_ROOT; }; 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackClientControl.h; path = ../common/JackClientControl.h; sourceTree = SOURCE_ROOT; }; 4BF8D1E10834EF5500C94B91 /* JackClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackClient.h; path = ../common/JackClient.h; sourceTree = SOURCE_ROOT; }; 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackClient.cpp; path = ../common/JackClient.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackAPI.cpp; path = ../common/JackAPI.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackInternalClient.cpp; path = ../common/JackInternalClient.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackInternalClient.h; path = ../common/JackInternalClient.h; sourceTree = SOURCE_ROOT; }; 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackServerAPI.cpp; path = ../common/JackServerAPI.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackExternalClient.h; path = ../common/JackExternalClient.h; sourceTree = SOURCE_ROOT; }; 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackExternalClient.cpp; path = ../common/JackExternalClient.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1FB0834EFD100C94B91 /* JackLibGlobals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackLibGlobals.h; path = ../common/JackLibGlobals.h; sourceTree = SOURCE_ROOT; }; 4BF8D1FC0834EFD100C94B91 /* JackLibClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackLibClient.h; path = ../common/JackLibClient.h; sourceTree = SOURCE_ROOT; }; 4BF8D1FD0834EFD100C94B91 /* JackLibClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackLibClient.cpp; path = ../common/JackLibClient.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D1FE0834EFD100C94B91 /* JackLibAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackLibAPI.cpp; path = ../common/JackLibAPI.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D2130834F02800C94B91 /* JackEngine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackEngine.h; path = ../common/JackEngine.h; sourceTree = SOURCE_ROOT; }; 4BF8D2140834F02800C94B91 /* JackEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackEngine.cpp; path = ../common/JackEngine.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D2190834F03D00C94B91 /* JackEngineControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackEngineControl.h; path = ../common/JackEngineControl.h; sourceTree = SOURCE_ROOT; }; 4BF8D2210834F05C00C94B91 /* JackServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackServer.cpp; path = ../common/JackServer.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D2220834F05C00C94B91 /* JackServer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackServer.h; path = ../common/JackServer.h; sourceTree = SOURCE_ROOT; }; 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Jackdmp.cpp; path = ../common/Jackdmp.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D2290834F07D00C94B91 /* JackAudioDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackAudioDriver.h; path = ../common/JackAudioDriver.h; sourceTree = SOURCE_ROOT; }; 4BF8D22A0834F07D00C94B91 /* JackAudioDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioDriver.cpp; path = ../common/JackAudioDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D23E0834F1C300C94B91 /* testAtomic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testAtomic.cpp; path = ../tests/testAtomic.cpp; sourceTree = SOURCE_ROOT; }; 4BF8D2470834F20600C94B91 /* testSem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSem.cpp; path = ../tests/testSem.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFrameTimer.cpp; path = ../common/JackFrameTimer.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFrameTimer.h; path = ../common/JackFrameTimer.h; sourceTree = SOURCE_ROOT; }; 4BFA5E980DEC4D9C00FA4CDB /* testMutex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testMutex; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testMutex.cpp; path = ../tests/testMutex.cpp; sourceTree = SOURCE_ROOT; }; 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA99A20AAAF3B0009E916C /* jack_iodelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_iodelay; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackGlobals.h; path = ../common/JackGlobals.h; sourceTree = SOURCE_ROOT; }; 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachThread.cpp; sourceTree = SOURCE_ROOT; }; 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachThread.h; sourceTree = SOURCE_ROOT; }; BA047C710E14E7540041F3B6 /* JackNetSocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetSocket.h; path = ../common/JackNetSocket.h; sourceTree = SOURCE_ROOT; }; BA222ACF0DC88132001A17F4 /* jack_net.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_net.so; sourceTree = BUILT_PRODUCTS_DIR; }; BA222AD60DC88268001A17F4 /* JackNetTool.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetTool.cpp; path = ../common/JackNetTool.cpp; sourceTree = SOURCE_ROOT; }; BA222AD70DC88268001A17F4 /* JackNetTool.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetTool.h; path = ../common/JackNetTool.h; sourceTree = SOURCE_ROOT; }; BA222ADC0DC882A5001A17F4 /* JackNetDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetDriver.cpp; path = ../common/JackNetDriver.cpp; sourceTree = SOURCE_ROOT; }; BA222ADD0DC882A5001A17F4 /* JackNetDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetDriver.h; path = ../common/JackNetDriver.h; sourceTree = SOURCE_ROOT; }; BA222AE90DC882DB001A17F4 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; BA222AEB0DC883B3001A17F4 /* JackNetManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetManager.cpp; path = ../common/JackNetManager.cpp; sourceTree = SOURCE_ROOT; }; BA222AEC0DC883B3001A17F4 /* JackNetManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetManager.h; path = ../common/JackNetManager.h; sourceTree = SOURCE_ROOT; }; C6859E8B029090EE04C91782 /* JackServer.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = JackServer.1; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 4B0A28E00D52073D002EFF74 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B0A29270D52108E002EFF74 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B19B2FB0E23620F00DD4A82 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B2021E0133A9BA40019E213 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B3224E010A3156800838A8E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B32252610A316B200838A8E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B32255B10A3187800838A8E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B32257510A3190C00838A8E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C41F0D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C47E0D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BCC87980D57168300A7FEB1 /* Accelerate.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C4F70D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BCC87990D57168300A7FEB1 /* Accelerate.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C50E0D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C51A0D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5260D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5320D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C53E0D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C54A0D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5580D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5640D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5700D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5800D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5940D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5A00D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5AC0D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5B80D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5C40D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5D00D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5E40D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5F80D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C60C0D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6190D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6240D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C62F0D4731D2000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6390D4731D3000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363DD20DEB02F6001F72D9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363E140DEB03C5001F72D9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363E480DEB0775001F72D9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363EE30DEB091C001F72D9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F180DEB0A6A001F72D9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F2F0DEB0BD1001F72D9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F6C0DEB0D4E001F72D9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B3811591326878E00C61B14 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B3811911326884E00C61B14 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B43A8B510145F6F00E52943 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B43A8E21014615800E52943 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B47ACD110B5890100469C67 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4B47ACD210B5890100469C67 /* Accelerate.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B5A1BB50CD1CB9E0005BF74 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B5A1BD40CD1CCE10005BF74 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B5E08D00E5B66EE00BEE4E0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B6654F1127C34AE00753A79 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699BAB097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699C42097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BCC87970D57168300A7FEB1 /* Accelerate.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CA7097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BCC87960D57168300A7FEB1 /* Accelerate.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CB5097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CC5097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CD5097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CE5097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CF7097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D07097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D1B097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D33097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D43097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D5B097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D73097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D8B097D421700A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D9C097D421700A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699DAB097D421700A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B8692D51371DB4700D2D11B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4B8692D61371DB4700D2D11B /* Accelerate.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B8F16DF13290DC80002AD73 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B8F16EC13290E0E0002AD73 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B978DB60A31CF4A009E2DD1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA339A610B2E36800190E3B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BA339A710B2E36800190E3B /* Accelerate.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BA692AA0CBE4BC700EAD520 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA692CE0CBE4C9000EAD520 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA7FEBD0D8E76270017FF73 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BD623F20CBCF0F000DE782F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDB981001FB9C00B15929 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBC01001FCC000B15929 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBE31001FD2D00B15929 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBFA1001FD7300B15929 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDC201001FDE300B15929 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BE6C69D0A3E096F005A203A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BE99D2A0AD7A04800C59091 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BF339070F8B864B0080FB5B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA5E910DEC4D9C00FA4CDB /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82860DF6A9E40087B4E1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82990DF6A9E40087B4E1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82A50DF6A9E40087B4E1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82B10DF6A9E40087B4E1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82BD0DF6A9E40087B4E1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82C90DF6A9E40087B4E1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA999C0AAAF3B0009E916C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; BA222ACA0DC88132001A17F4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; BA222AE40DC882DB001A17F4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( 4BCC87950D57168300A7FEB1 /* Accelerate.framework */, ); name = "External Frameworks and Libraries"; sourceTree = ""; }; 08FB7794FE84155DC02AAC07 /* JackServer */ = { isa = PBXGroup; children = ( 08FB7795FE84155DC02AAC07 /* Source */, C6859E8C029090F304C91782 /* Documentation */, 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */, 1AB674ADFE9D54B511CA2CBB /* Products */, 4B464301076CAC7700E5077C /* Jack-Info.plist */, ); name = JackServer; sourceTree = ""; }; 08FB7795FE84155DC02AAC07 /* Source */ = { isa = PBXGroup; children = ( 4B05A09D0DF72C6000840F4C /* Additional */, 4B6BEB4A07A6CCDC00A5DBDA /* Tests */, 4B37C20006DF1F900016E567 /* Latency */, 4B03383E0797E19900686131 /* Simple clients */, 4B765CC805ECE17900571F78 /* Tools */, 4BA550FC05E2421400569492 /* Shm */, 4BA33DF905EDFD8C000CCD5F /* Thread */, 4BA3874007947A46008D8992 /* Synchro */, 4BA550FF05E2423600569492 /* Channels */, 4BA550F605E241B800569492 /* Driver */, 4BA3873B079479C2008D8992 /* Graph */, 4BA550FA05E241F200569492 /* Ports */, 4BD56D74079687D7006D44F9 /* Client */, 4B9B627005E60A9E001E19AA /* Server */, ); name = Source; sourceTree = ""; }; 1AB674ADFE9D54B511CA2CBB /* Products */ = { isa = PBXGroup; children = ( 4B699BB1097D421600A18468 /* jackdmp */, 4B699C47097D421600A18468 /* Jackmp.framework */, 4B699CAC097D421600A18468 /* Jackservermp.framework */, 4B699CBB097D421600A18468 /* jack_metro */, 4B699CCB097D421600A18468 /* jack_lsp */, 4B699CDB097D421600A18468 /* jack_connect */, 4B699CEB097D421600A18468 /* jack_disconnect */, 4B699CFD097D421600A18468 /* jack_freewheel */, 4B699D0D097D421600A18468 /* jack_external_metro */, 4B699D21097D421600A18468 /* testAtomic */, 4B699D39097D421600A18468 /* testSem */, 4B699D49097D421600A18468 /* zombie */, 4B699D61097D421600A18468 /* synchroServer */, 4B699D79097D421600A18468 /* synchroClient */, 4B699D91097D421700A18468 /* synchroServerClient */, 4B699DA1097D421700A18468 /* jack_coreaudio.so */, 4B699DB0097D421700A18468 /* jack_dummy.so */, 4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */, 4BE6C6A30A3E096F005A203A /* jack_test */, 4BFA99A20AAAF3B0009E916C /* jack_iodelay */, 4BE99D300AD7A04800C59091 /* jack_cpu */, 4BD623F70CBCF0F000DE782F /* inprocess.so */, 4BA692B00CBE4BC700EAD520 /* jack_load */, 4BA692D40CBE4C9000EAD520 /* jack_unload */, 4B5A1BBB0CD1CB9E0005BF74 /* jack_midiseq */, 4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */, 4B35C4250D4731D1000DE7AE /* jackdmp */, 4B35C4830D4731D1000DE7AE /* Jackmp.framework */, 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */, 4B35C5140D4731D1000DE7AE /* jack_midiseq */, 4B35C5200D4731D1000DE7AE /* jack_midisine */, 4B35C52C0D4731D1000DE7AE /* jack_metro */, 4B35C5380D4731D1000DE7AE /* jack_lsp */, 4B35C5440D4731D1000DE7AE /* jack_connect */, 4B35C5500D4731D1000DE7AE /* jack_disconnect */, 4B35C55E0D4731D2000DE7AE /* jack_freewheel */, 4B35C56A0D4731D2000DE7AE /* jack_iodelay */, 4B35C5760D4731D2000DE7AE /* jack_external_metro */, 4B35C5860D4731D2000DE7AE /* testAtomic */, 4B35C59A0D4731D2000DE7AE /* testSem */, 4B35C5A60D4731D2000DE7AE /* zombie */, 4B35C5B20D4731D2000DE7AE /* jack_test */, 4B35C5BE0D4731D2000DE7AE /* jack_cpu */, 4B35C5CA0D4731D2000DE7AE /* jack_load */, 4B35C5D60D4731D2000DE7AE /* jack_unload */, 4B35C5EA0D4731D2000DE7AE /* synchroServer */, 4B35C5FE0D4731D2000DE7AE /* synchroClient */, 4B35C6120D4731D2000DE7AE /* synchroServerClient */, 4B35C61E0D4731D2000DE7AE /* jack_coreaudio.so */, 4B35C6290D4731D2000DE7AE /* jack_portaudio.so */, 4B35C6340D4731D2000DE7AE /* jack_dummy.so */, 4B35C63E0D4731D3000DE7AE /* inprocess.so */, 4B0A28E60D52073D002EFF74 /* jack_thread_wait */, 4B0A292D0D52108E002EFF74 /* jack_thread_wait */, 4B57F5950D72C27900B4E719 /* jack_thread_wait */, 4BA7FEC30D8E76270017FF73 /* jack_server_control */, BA222ACF0DC88132001A17F4 /* jack_net.so */, BA222AE90DC882DB001A17F4 /* netmanager.so */, 4BA7FEC30D8E76270017FF73 /* jack_server_control */, 4B363DD80DEB02F6001F72D9 /* jack_alias */, 4B363E1A0DEB03C5001F72D9 /* jack_evmon */, 4B363E4E0DEB0775001F72D9 /* jack_bufsize */, 4B363EE90DEB091C001F72D9 /* jack_rec */, 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */, 4B363F350DEB0BD1001F72D9 /* jack_showtime */, 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */, 4BFA5E980DEC4D9C00FA4CDB /* testMutex */, 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */, 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */, 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */, 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */, 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */, 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */, 4B19B3000E23620F00DD4A82 /* audioadapter.so */, 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */, 4BF3390C0F8B864B0080FB5B /* jack_coremidi.so */, 4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */, 4BDCDBC51001FCC000B15929 /* jack_net.so */, 4BDCDBE81001FD2D00B15929 /* netmanager.so */, 4BDCDBFF1001FD7300B15929 /* audioadapter.so */, 4BDCDC251001FDE300B15929 /* netadapter.so */, 4B43A8BA10145F6F00E52943 /* jack_loopback.so */, 4B43A8E71014615800E52943 /* jack_loopback.so */, 4B3224E510A3156800838A8E /* jack_netone.so */, 4B32252B10A316B200838A8E /* jack_netone.so */, 4B32256110A3187800838A8E /* jack_netsource */, 4B32257B10A3190C00838A8E /* jack_netsource */, 4BA339AC10B2E36800190E3B /* Jackservermp.framework */, 4B47ACD710B5890100469C67 /* Jackmp.framework */, 4B6654F7127C34AE00753A79 /* jack_server_control */, 4B38115F1326878E00C61B14 /* jack_latent_client */, 4B3811971326884E00C61B14 /* jack_latent_client */, 4B8F16E513290DC80002AD73 /* jack_midi_dump */, 4B8F16F213290E0E0002AD73 /* jack_midi_dump */, 4B2021E6133A9BA40019E213 /* jack_midi_latency_test */, 4B8692DB1371DB4700D2D11B /* Jacknet.framework */, ); name = Products; sourceTree = ""; }; 4B03383E0797E19900686131 /* Simple clients */ = { isa = PBXGroup; children = ( 4B202209133A9C1C0019E213 /* midi_latency_test.c */, 4B8F16F41329161E0002AD73 /* midi_dump.c */, 4B3811FA13269C8300C61B14 /* latent_client.c */, 4B6654FB127C350100753A79 /* server_control.cpp */, 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */, 4B363F220DEB0AB0001F72D9 /* monitor_client.c */, 4B363EED0DEB094B001F72D9 /* capture_client.c */, 4B363E710DEB0808001F72D9 /* bufsize.c */, 4B363E200DEB0401001F72D9 /* evmon.c */, 4B363DDE0DEB034E001F72D9 /* alias.c */, 4BA7FEC80D8E76650017FF73 /* control.c */, 4B0A28EC0D520852002EFF74 /* tw.c */, 4B5A1BDC0CD1CD420005BF74 /* midisine.c */, 4B5A1BBD0CD1CC110005BF74 /* midiseq.c */, 4BA692D60CBE4CC600EAD520 /* ipunload.c */, 4BA692B20CBE4C2D00EAD520 /* ipload.c */, 4BD6240C0CBCF16600DE782F /* inprocess.c */, 4B60CE480AAABA31004956AA /* connect.c */, 4BF8D1670834EDD900C94B91 /* zombie.c */, 4BF8D1690834EDE600C94B91 /* lsp.c */, 4BF8D16B0834EDF000C94B91 /* metro.c */, 4BF8D1710834EE0F00C94B91 /* freewheel.c */, 4B363F3D0DEB0C31001F72D9 /* showtime.c */, ); name = "Simple clients"; sourceTree = ""; }; 4B05A0420DF72B8500840F4C /* Linux */ = { isa = PBXGroup; children = ( 4B05A07D0DF72BC000840F4C /* driver.h */, 4B49D3C914864DA7003390F8 /* JackLinuxTime.c */, 4B349837133A6B6F00D130AB /* firewire */, 4B349825133A6AF500D130AB /* alsarawmidi */, 4B05A04C0DF72BC000840F4C /* alsa */, 4B05A0820DF72BC000840F4C /* freebob */, ); name = Linux; sourceTree = ""; }; 4B05A04C0DF72BC000840F4C /* alsa */ = { isa = PBXGroup; children = ( 4BA2574C132FB49B009F2D3F /* alsa_driver.c */, 4B05A04D0DF72BC000840F4C /* alsa_driver.h */, 4B05A04E0DF72BC000840F4C /* alsa_midi.h */, 4B05A04F0DF72BC000840F4C /* alsa_midi_impl.h */, 4B05A0500DF72BC000840F4C /* alsa_midi_jackmp.cpp */, 4B05A0510DF72BC000840F4C /* alsa_rawmidi.c */, 4B05A0520DF72BC000840F4C /* alsa_seqmidi.c */, 4B05A0530DF72BC000840F4C /* bitset.h */, 4B05A0540DF72BC000840F4C /* generic.h */, 4B05A0550DF72BC000840F4C /* generic_hw.c */, 4B05A0560DF72BC000840F4C /* hammerfall.c */, 4B05A0570DF72BC000840F4C /* hammerfall.h */, 4B05A0580DF72BC000840F4C /* hardware.h */, 4B05A0590DF72BC000840F4C /* hdsp.c */, 4B05A05A0DF72BC000840F4C /* hdsp.h */, 4B05A05B0DF72BC000840F4C /* ice1712.c */, 4B05A05C0DF72BC000840F4C /* ice1712.h */, 4B05A05D0DF72BC000840F4C /* JackAlsaDriver.cpp */, 4B05A05E0DF72BC000840F4C /* JackAlsaDriver.h */, 4B05A05F0DF72BC000840F4C /* jslist.h */, 4B05A0620DF72BC000840F4C /* midi_pack.h */, 4B05A0630DF72BC000840F4C /* midi_unpack.h */, 4B05A0640DF72BC000840F4C /* usx2y.c */, 4B05A0650DF72BC000840F4C /* usx2y.h */, ); name = alsa; path = ../linux/alsa; sourceTree = SOURCE_ROOT; }; 4B05A0820DF72BC000840F4C /* freebob */ = { isa = PBXGroup; children = ( 4B05A0830DF72BC000840F4C /* freebob_driver.h */, 4B05A0840DF72BC000840F4C /* JackFreebobDriver.cpp */, 4B05A0850DF72BC000840F4C /* JackFreebobDriver.h */, ); name = freebob; path = ../linux/freebob; sourceTree = SOURCE_ROOT; }; 4B05A08A0DF72BF600840F4C /* Windows */ = { isa = PBXGroup; children = ( 4B49D3D814864DEC003390F8 /* JackWinThread.cpp */, 4B49D3D914864DEC003390F8 /* JackWinServerLaunch.cpp */, 4B49D3DA14864DEC003390F8 /* JackWinSemaphore.cpp */, 4B49D3DB14864DEC003390F8 /* JackWinProcessSync.cpp */, 4B49D3DC14864DEC003390F8 /* JackWinNamedPipeServerNotifyChannel.cpp */, 4B49D3DD14864DEC003390F8 /* JackWinNamedPipeServerChannel.cpp */, 4B49D3DE14864DEC003390F8 /* JackWinNamedPipeNotifyChannel.cpp */, 4B49D3DF14864DEC003390F8 /* JackWinNamedPipeClientChannel.cpp */, 4B49D3E014864DED003390F8 /* JackWinNamedPipe.cpp */, 4B49D3E114864DED003390F8 /* JackWinEvent.cpp */, 4B49D3E214864DED003390F8 /* JackNetWinSocket.cpp */, 4B49D3E314864DED003390F8 /* JackMMCSS.cpp */, 4B49D3E414864DED003390F8 /* JackWinTime.c */, 4B49D3EA14864DED003390F8 /* JackWinThread.h */, 4B49D3EB14864DED003390F8 /* JackWinSemaphore.h */, 4B49D3EC14864DED003390F8 /* JackWinProcessSync.h */, 4B49D3ED14864DED003390F8 /* JackWinNamedPipeServerNotifyChannel.h */, 4B49D3EE14864DED003390F8 /* JackWinNamedPipeServerChannel.h */, 4B49D3EF14864DED003390F8 /* JackWinNamedPipeNotifyChannel.h */, 4B49D3F014864DED003390F8 /* JackWinNamedPipeClientChannel.h */, 4B49D3F114864DED003390F8 /* JackWinNamedPipe.h */, 4B49D3F214864DED003390F8 /* JackWinMutex.h */, 4B49D3F314864DED003390F8 /* JackWinEvent.h */, 4B49D3F814864DED003390F8 /* JackNetWinSocket.h */, 4B49D3F914864DED003390F8 /* JackMMCSS.h */, 4B49D3BB14864D49003390F8 /* portaudio */, 4B49D3B214864D41003390F8 /* winmme */, ); name = Windows; sourceTree = ""; }; 4B05A09D0DF72C6000840F4C /* Additional */ = { isa = PBXGroup; children = ( 4B90676814BEFB270074CD40 /* Solaris */, 4B05A08A0DF72BF600840F4C /* Windows */, 4B05A0420DF72B8500840F4C /* Linux */, ); name = Additional; sourceTree = ""; }; 4B19B3010E23629800DD4A82 /* Adapter */ = { isa = PBXGroup; children = ( 4BE5FECF0E725C320020B576 /* JackCoreAudioAdapter.cpp */, 4BE5FED00E725C320020B576 /* JackCoreAudioAdapter.h */, 4BF4BAB00E3480AB00403CDF /* JackAudioAdapterFactory.cpp */, 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */, 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */, 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */, 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */, 4B19B30C0E2362E700DD4A82 /* JackException.h */, 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */, 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */, 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */, ); name = Adapter; sourceTree = ""; }; 4B349825133A6AF500D130AB /* alsarawmidi */ = { isa = PBXGroup; children = ( 4B349826133A6AF500D130AB /* JackALSARawMidiDriver.cpp */, 4B349827133A6AF500D130AB /* JackALSARawMidiDriver.h */, 4B349828133A6AF500D130AB /* JackALSARawMidiInputPort.cpp */, 4B349829133A6AF500D130AB /* JackALSARawMidiInputPort.h */, 4B34982A133A6AF500D130AB /* JackALSARawMidiOutputPort.cpp */, 4B34982B133A6AF500D130AB /* JackALSARawMidiOutputPort.h */, 4B34982C133A6AF500D130AB /* JackALSARawMidiPort.cpp */, 4B34982D133A6AF500D130AB /* JackALSARawMidiPort.h */, 4B34982E133A6AF500D130AB /* JackALSARawMidiReceiveQueue.cpp */, 4B34982F133A6AF500D130AB /* JackALSARawMidiReceiveQueue.h */, 4B349830133A6AF500D130AB /* JackALSARawMidiSendQueue.cpp */, 4B349831133A6AF500D130AB /* JackALSARawMidiSendQueue.h */, ); name = alsarawmidi; path = ../linux/alsarawmidi; sourceTree = SOURCE_ROOT; }; 4B349837133A6B6F00D130AB /* firewire */ = { isa = PBXGroup; children = ( 4B349838133A6B6F00D130AB /* ffado_driver.h */, 4B349839133A6B6F00D130AB /* JackFFADODriver.cpp */, 4B34983A133A6B6F00D130AB /* JackFFADODriver.h */, 4B34983B133A6B6F00D130AB /* JackFFADOMidiInputPort.cpp */, 4B34983C133A6B6F00D130AB /* JackFFADOMidiInputPort.h */, 4B34983D133A6B6F00D130AB /* JackFFADOMidiOutputPort.cpp */, 4B34983E133A6B6F00D130AB /* JackFFADOMidiOutputPort.h */, 4B34983F133A6B6F00D130AB /* JackFFADOMidiReceiveQueue.cpp */, 4B349840133A6B6F00D130AB /* JackFFADOMidiReceiveQueue.h */, 4B349841133A6B6F00D130AB /* JackFFADOMidiSendQueue.cpp */, 4B349842133A6B6F00D130AB /* JackFFADOMidiSendQueue.h */, ); name = firewire; path = ../linux/firewire; sourceTree = SOURCE_ROOT; }; 4B37C20006DF1F900016E567 /* Latency */ = { isa = PBXGroup; children = ( ); name = Latency; sourceTree = ""; }; 4B49D3B214864D41003390F8 /* winmme */ = { isa = PBXGroup; children = ( 4B49D3B314864D41003390F8 /* JackWinMMEDriver.cpp */, 4B49D3B414864D41003390F8 /* JackWinMMEDriver.h */, 4B49D3B514864D41003390F8 /* JackWinMMEInputPort.cpp */, 4B49D3B614864D41003390F8 /* JackWinMMEInputPort.h */, 4B49D3B714864D41003390F8 /* JackWinMMEOutputPort.cpp */, 4B49D3B814864D41003390F8 /* JackWinMMEOutputPort.h */, 4B49D3B914864D41003390F8 /* JackWinMMEPort.cpp */, 4B49D3BA14864D41003390F8 /* JackWinMMEPort.h */, ); name = winmme; path = ../windows/winmme; sourceTree = SOURCE_ROOT; }; 4B49D3BB14864D49003390F8 /* portaudio */ = { isa = PBXGroup; children = ( 4B49D3BC14864D49003390F8 /* JackPortAudioAdapter.cpp */, 4B49D3BD14864D49003390F8 /* JackPortAudioAdapter.h */, 4B49D3BE14864D49003390F8 /* JackPortAudioDevices.cpp */, 4B49D3BF14864D49003390F8 /* JackPortAudioDevices.h */, 4B49D3C014864D49003390F8 /* JackPortAudioDriver.cpp */, 4B49D3C114864D49003390F8 /* JackPortAudioDriver.h */, 4B49D3C214864D49003390F8 /* pa_asio.h */, 4B49D3C314864D49003390F8 /* portaudio.h */, ); name = portaudio; path = ../windows/portaudio; sourceTree = SOURCE_ROOT; }; 4B6BEB4A07A6CCDC00A5DBDA /* Tests */ = { isa = PBXGroup; children = ( 4B38141F1327AA6800C61B14 /* iodelay.cpp */, 4B3F49070AD8503300491C6E /* cpu.c */, 4BF8D23E0834F1C300C94B91 /* testAtomic.cpp */, 4BF8D2470834F20600C94B91 /* testSem.cpp */, 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */, 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */, 4BBD13CC08C71EB40079F7FF /* testSynchroServerClient.cpp */, 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */, 4BE6C6AC0A3E0A65005A203A /* test.cpp */, ); name = Tests; sourceTree = ""; }; 4B6C73780CC60A6D001AFFD4 /* jack */ = { isa = PBXGroup; children = ( 4B49D44014865F22003390F8 /* net.h */, 4B49D44114865F22003390F8 /* session.h */, 4B94334910A5E666002A187F /* systemdeps.h */, 4B9A26000DBF8584006E9FBC /* jslist.h */, 4B95BCAD0D913073000F7695 /* control.h */, 4B6B9EF50CD0958B0051EE5A /* midiport.h */, 4B6C73790CC60A6D001AFFD4 /* intclient.h */, 4B6C737A0CC60A6D001AFFD4 /* jack.h */, 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */, 4B6C737C0CC60A6D001AFFD4 /* statistics.h */, 4B6C737D0CC60A6D001AFFD4 /* thread.h */, 4B6C737E0CC60A6D001AFFD4 /* transport.h */, 4B6C737F0CC60A6D001AFFD4 /* types.h */, 4B88D03911298BEE007A87C1 /* weakjack.h */, 4B88D03A11298BEE007A87C1 /* weakmacros.h */, ); name = jack; path = ../common/jack; sourceTree = SOURCE_ROOT; }; 4B765CC805ECE17900571F78 /* Tools */ = { isa = PBXGroup; children = ( 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */, 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */, 4BF5FBC80E878D24003D2374 /* JackMachTime.c */, 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */, 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */, 4B9A25B30DBF8330006E9FBC /* JackError.cpp */, 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */, 4BF8D1770834EE4800C94B91 /* JackError.h */, 4BF8D1830834EE5800C94B91 /* JackTime.h */, ); name = Tools; sourceTree = ""; }; 4B90676814BEFB270074CD40 /* Solaris */ = { isa = PBXGroup; children = ( 4B90679914BEFB500074CD40 /* JackSolarisTime.c */, 4B90679A14BEFB5A0074CD40 /* JackBoomerDriver.cpp */, 4B90679B14BEFB5A0074CD40 /* JackBoomerDriver.h */, 4B90679C14BEFB5A0074CD40 /* JackOSSAdapter.cpp */, 4B90679D14BEFB5A0074CD40 /* JackOSSAdapter.h */, 4B90679E14BEFB5A0074CD40 /* JackOSSDriver.cpp */, 4B90679F14BEFB5A0074CD40 /* JackOSSDriver.h */, ); name = Solaris; sourceTree = ""; }; 4B9B627005E60A9E001E19AA /* Server */ = { isa = PBXGroup; children = ( 4B6C73780CC60A6D001AFFD4 /* jack */, 4B67AB8C14B4B03800B4AA9A /* JackException.cpp */, 4BE4CC000CDA153400CCF5BB /* JackTools.h */, 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */, 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */, 4B4E9AF90E5F1090000A3278 /* JackControlAPI.h */, 4B66A8580934964500A89560 /* JackConstants.h */, 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */, 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */, 4BF8D2190834F03D00C94B91 /* JackEngineControl.h */, 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */, 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */, 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */, 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */, 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */, 4BF8D2220834F05C00C94B91 /* JackServer.h */, 4BF8D2210834F05C00C94B91 /* JackServer.cpp */, 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */, 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */, 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */, ); name = Server; sourceTree = ""; }; 4BA33DF905EDFD8C000CCD5F /* Thread */ = { isa = PBXGroup; children = ( 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */, 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */, 4BF8D19F0834EE9E00C94B91 /* JackThread.h */, 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */, 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */, ); name = Thread; sourceTree = ""; }; 4BA3873B079479C2008D8992 /* Graph */ = { isa = PBXGroup; children = ( 4BF772FD08B3330F00149912 /* JackAtomic.h */, 4BF8D1C10834EF0800C94B91 /* JackAtomicState.h */, 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */, 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */, 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */, 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */, ); name = Graph; sourceTree = ""; }; 4BA3874007947A46008D8992 /* Synchro */ = { isa = PBXGroup; children = ( 4BB4214914D2C0A700A1CAE1 /* JackPosixProcessSync.cpp */, 4BB4214A14D2C0A700A1CAE1 /* JackPosixProcessSync.h */, 4B327BA614B4B50400976483 /* JackPosixMutex.cpp */, 4BB4214814D2C0A700A1CAE1 /* JackPosixMutex.h */, 4BC3B6B70E703BAA0066E42F /* JackPosixSemaphore.cpp */, 4BC3B6B80E703BAA0066E42F /* JackPosixSemaphore.h */, 4BD561C708EEB910006BBC2A /* JackSynchro.h */, 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */, 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */, 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */, 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */, 4BC8326D0DF42C7D00DD1C93 /* JackMutex.h */, ); name = Synchro; sourceTree = ""; }; 4BA550F605E241B800569492 /* Driver */ = { isa = PBXGroup; children = ( 4B869B3D08C8D21C001CF041 /* driver_interface.h */, 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */, 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */, 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */, 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */, 4BF8D1B50834EEE400C94B91 /* JackDriver.h */, 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */, 4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */, 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */, 4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */, 4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */, 4BF3390D0F8B86AF0080FB5B /* MIDI */, 4B19B3010E23629800DD4A82 /* Adapter */, 4BD56D8707968982006D44F9 /* Threaded */, BA222AEA0DC88379001A17F4 /* Net */, 4BD56D8607968979006D44F9 /* Audio */, ); name = Driver; sourceTree = ""; }; 4BA550F905E241D900569492 /* Library */ = { isa = PBXGroup; children = ( 4BF8D1FB0834EFD100C94B91 /* JackLibGlobals.h */, 4BF8D1FC0834EFD100C94B91 /* JackLibClient.h */, 4BF8D1FD0834EFD100C94B91 /* JackLibClient.cpp */, 4BF8D1FE0834EFD100C94B91 /* JackLibAPI.cpp */, ); name = Library; sourceTree = ""; }; 4BA550FA05E241F200569492 /* Ports */ = { isa = PBXGroup; children = ( 4BA550FB05E2420000569492 /* Engine */, 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */, 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */, 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */, 4BAB95B70B9E20B800A0C723 /* JackPortType.h */, 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */, 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */, 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */, ); name = Ports; sourceTree = ""; }; 4BA550FB05E2420000569492 /* Engine */ = { isa = PBXGroup; children = ( 4B193990133F321500547810 /* JackFilters.h */, 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */, 4BF8D2130834F02800C94B91 /* JackEngine.h */, 4BF8D2140834F02800C94B91 /* JackEngine.cpp */, 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */, 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */, ); name = Engine; sourceTree = ""; }; 4BA550FC05E2421400569492 /* Shm */ = { isa = PBXGroup; children = ( 4BF8D18F0834EE8400C94B91 /* shm.h */, 4BF8D1900834EE8400C94B91 /* shm.c */, 4BF8D1870834EE7900C94B91 /* JackShmMem.h */, 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */, ); name = Shm; sourceTree = ""; }; 4BA550FF05E2423600569492 /* Channels */ = { isa = PBXGroup; children = ( 4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */, 4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */, 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */, 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */, 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */, 4BF8D1B30834EED500C94B91 /* JackInternalClientChannel.h */, 4BB371D40C1AD85A0050C1E4 /* JackNotification.h */, 4BFB299908AF452300D450D4 /* Socket */, ); name = Channels; sourceTree = ""; }; 4BD56D73079687AD006D44F9 /* External */ = { isa = PBXGroup; children = ( 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */, 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */, ); name = External; sourceTree = ""; }; 4BD56D74079687D7006D44F9 /* Client */ = { isa = PBXGroup; children = ( 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */, 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */, 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */, 4BF8D1E10834EF5500C94B91 /* JackClient.h */, 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */, 4B98AE010931D30C0091932A /* JackDebugClient.h */, 4B98AE000931D30C0091932A /* JackDebugClient.cpp */, 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */, 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */, 4BF520580CB8D1010037470E /* timestamps.h */, 4BF520520CB8D0E80037470E /* timestamps.c */, 4BD56D75079687EB006D44F9 /* Internal */, 4BD56D73079687AD006D44F9 /* External */, 4BA550F905E241D900569492 /* Library */, ); name = Client; sourceTree = ""; }; 4BD56D75079687EB006D44F9 /* Internal */ = { isa = PBXGroup; children = ( 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */, 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */, 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */, ); name = "Internal "; sourceTree = ""; }; 4BD56D8607968979006D44F9 /* Audio */ = { isa = PBXGroup; children = ( 4BAA150114F04FB600402512 /* JackAC3Encoder.cpp */, 4BAA150214F04FB600402512 /* JackAC3Encoder.h */, 4BBB00CF0E72614F0018AB1B /* JackPortAudioDevices.cpp */, 4BBB00D00E72614F0018AB1B /* JackPortAudioDevices.h */, 4BBB00D10E72614F0018AB1B /* JackPortAudioDriver.cpp */, 4BBB00D20E72614F0018AB1B /* JackPortAudioDriver.h */, 4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */, 4BE5FECC0E725C090020B576 /* JackCoreAudioDriver.h */, 4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */, 4BF8D2290834F07D00C94B91 /* JackAudioDriver.h */, 4BF8D22A0834F07D00C94B91 /* JackAudioDriver.cpp */, ); name = Audio; sourceTree = ""; }; 4BD56D8707968982006D44F9 /* Threaded */ = { isa = PBXGroup; children = ( 4BF8D1BD0834EEFC00C94B91 /* JackThreadedDriver.h */, 4BF8D1BE0834EEFC00C94B91 /* JackThreadedDriver.cpp */, 4BF8D1B90834EEF100C94B91 /* JackFreewheelDriver.h */, 4BF8D1BA0834EEF100C94B91 /* JackFreewheelDriver.cpp */, 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */, 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */, 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */, 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */, ); name = Threaded; sourceTree = ""; }; 4BF3390D0F8B86AF0080FB5B /* MIDI */ = { isa = PBXGroup; children = ( 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */, 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */, 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */, 4B193976133F31CB00547810 /* JackMidiSendQueue.h */, 4B193977133F31CB00547810 /* JackMidiUtil.cpp */, 4B193978133F31CB00547810 /* JackMidiUtil.h */, 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */, 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */, 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */, 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */, 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */, 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */, 4B193945133F315200547810 /* JackMidiReadQueue.cpp */, 4B193946133F315200547810 /* JackMidiReadQueue.h */, 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */, 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */, 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */, 4B193932133F311400547810 /* JackMidiAsyncQueue.h */, 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */, 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */, 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */, 4B370A17133DD7E200237B68 /* JackCoreMidiOutputPort.h */, 4B370A18133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.cpp */, 4B370A19133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.h */, 4B370A1A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp */, 4B370A1B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h */, 4B370A1C133DD7E300237B68 /* JackCoreMidiPort.cpp */, 4B370A1D133DD7E300237B68 /* JackCoreMidiPort.h */, 4B370A1E133DD7E300237B68 /* JackCoreMidiUtil.cpp */, 4B370A1F133DD7E300237B68 /* JackCoreMidiUtil.h */, 4B370A20133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp */, 4B370A21133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h */, 4B370A22133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp */, 4B370A23133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h */, 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */, 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */, 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */, 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */, ); name = MIDI; sourceTree = ""; }; 4BFB299908AF452300D450D4 /* Socket */ = { isa = PBXGroup; children = ( 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */, 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */, 4BC3B6AF0E703B8D0066E42F /* JackSocketClientChannel.cpp */, 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */, 4BC3B6B10E703B8D0066E42F /* JackSocketNotifyChannel.cpp */, 4BC3B6B20E703B8D0066E42F /* JackSocketNotifyChannel.h */, 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */, 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */, 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */, 4BC3B6B60E703B8D0066E42F /* JackSocketServerNotifyChannel.h */, ); name = Socket; sourceTree = ""; }; BA222AEA0DC88379001A17F4 /* Net */ = { isa = PBXGroup; children = ( 4B8693151371DD0A00D2D11B /* JackNetAPI.cpp */, 4B32256310A318E300838A8E /* netsource.c */, 4B3224EC10A315C400838A8E /* netjack_packet.c */, 4B3224ED10A315C400838A8E /* netjack_packet.h */, 4B3224EE10A315C400838A8E /* netjack.c */, 4B3224EF10A315C400838A8E /* netjack.h */, 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */, 4B3224E910A315B100838A8E /* JackNetOneDriver.h */, 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */, 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */, 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */, 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */, 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */, 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */, BA222ADD0DC882A5001A17F4 /* JackNetDriver.h */, BA222ADC0DC882A5001A17F4 /* JackNetDriver.cpp */, BA047C710E14E7540041F3B6 /* JackNetSocket.h */, BA222AEB0DC883B3001A17F4 /* JackNetManager.cpp */, BA222AEC0DC883B3001A17F4 /* JackNetManager.h */, BA222AD60DC88268001A17F4 /* JackNetTool.cpp */, BA222AD70DC88268001A17F4 /* JackNetTool.h */, ); name = Net; sourceTree = ""; }; C6859E8C029090F304C91782 /* Documentation */ = { isa = PBXGroup; children = ( C6859E8B029090EE04C91782 /* JackServer.1 */, ); name = Documentation; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 4B0A28DD0D52073D002EFF74 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B0A29240D52108E002EFF74 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B19B2F70E23620F00DD4A82 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B19B3140E2362E800DD4A82 /* JackAudioAdapter.h in Headers */, 4B19B3160E2362E800DD4A82 /* JackAudioAdapterInterface.h in Headers */, 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */, 4BE5FED20E725C320020B576 /* JackCoreAudioAdapter.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B2021DD133A9BA40019E213 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B3224D810A3156800838A8E /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B3224EB10A315B100838A8E /* JackNetOneDriver.h in Headers */, 4B3224F110A315C400838A8E /* netjack_packet.h in Headers */, 4B3224F310A315C400838A8E /* netjack.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B32251E10A316B200838A8E /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B32253210A3173A00838A8E /* JackNetOneDriver.h in Headers */, 4B32253410A3173C00838A8E /* netjack.h in Headers */, 4B32253610A3173E00838A8E /* netjack_packet.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B32255810A3187800838A8E /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B32256E10A318FD00838A8E /* netjack_packet.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B32257210A3190C00838A8E /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B32258010A3195A00838A8E /* netjack_packet.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C41C0D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B9A26040DBF8584006E9FBC /* jslist.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C4280D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B35C42A0D4731D1000DE7AE /* JackError.h in Headers */, 4B35C42B0D4731D1000DE7AE /* JackTime.h in Headers */, 4B35C42C0D4731D1000DE7AE /* JackShmMem.h in Headers */, 4B35C42D0D4731D1000DE7AE /* shm.h in Headers */, 4B35C42F0D4731D1000DE7AE /* JackThread.h in Headers */, 4B35C4300D4731D1000DE7AE /* JackActivationCount.h in Headers */, 4B35C4310D4731D1000DE7AE /* JackChannel.h in Headers */, 4B35C4320D4731D1000DE7AE /* JackGraphManager.h in Headers */, 4B35C4330D4731D1000DE7AE /* JackPort.h in Headers */, 4B35C4340D4731D1000DE7AE /* JackClientInterface.h in Headers */, 4B35C4350D4731D1000DE7AE /* JackClientControl.h in Headers */, 4B35C4360D4731D1000DE7AE /* JackClient.h in Headers */, 4B35C4370D4731D1000DE7AE /* JackInternalClient.h in Headers */, 4B35C4380D4731D1000DE7AE /* JackLibGlobals.h in Headers */, 4B35C4390D4731D1000DE7AE /* JackLibClient.h in Headers */, 4B35C43A0D4731D1000DE7AE /* JackConnectionManager.h in Headers */, 4B35C43B0D4731D1000DE7AE /* JackFrameTimer.h in Headers */, 4B35C43D0D4731D1000DE7AE /* JackMachSemaphore.h in Headers */, 4B35C43E0D4731D1000DE7AE /* JackGlobals.h in Headers */, 4B35C43F0D4731D1000DE7AE /* JackMachThread.h in Headers */, 4B35C4460D4731D1000DE7AE /* JackSynchro.h in Headers */, 4B35C4470D4731D1000DE7AE /* JackDebugClient.h in Headers */, 4B35C4480D4731D1000DE7AE /* JackConstants.h in Headers */, 4B35C4490D4731D1000DE7AE /* JackTransportEngine.h in Headers */, 4B35C44A0D4731D1000DE7AE /* timestamps.h in Headers */, 4B35C44B0D4731D1000DE7AE /* intclient.h in Headers */, 4B35C44C0D4731D1000DE7AE /* jack.h in Headers */, 4B35C44D0D4731D1000DE7AE /* ringbuffer.h in Headers */, 4B35C44E0D4731D1000DE7AE /* statistics.h in Headers */, 4B35C44F0D4731D1000DE7AE /* thread.h in Headers */, 4B35C4500D4731D1000DE7AE /* transport.h in Headers */, 4B35C4510D4731D1000DE7AE /* types.h in Headers */, 4B35C4520D4731D1000DE7AE /* JackPortType.h in Headers */, 4B35C4530D4731D1000DE7AE /* JackMidiPort.h in Headers */, 4B35C4540D4731D1000DE7AE /* midiport.h in Headers */, 4B35C4550D4731D1000DE7AE /* JackTools.h in Headers */, 4B9A26050DBF8584006E9FBC /* jslist.h in Headers */, 4B4F9C910DC20C0400706CB0 /* JackMessageBuffer.h in Headers */, 4B93F19E0E87998400E4ECCD /* JackPosixThread.h in Headers */, 4B88D03F11298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04011298BEE007A87C1 /* weakmacros.h in Headers */, 4B8A38F0117B827900664E07 /* JackSocket.h in Headers */, 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */, 4B5160A813215E8B00BB7DCB /* systemdeps.h in Headers */, 4B193993133F321500547810 /* JackFilters.h in Headers */, 4B49D44614865F22003390F8 /* net.h in Headers */, 4B49D44714865F22003390F8 /* session.h in Headers */, 4B1499F714BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, 4BB4215114D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */, 4BB4215314D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */, 4B4C3B651BC2FF6A0004CC35 /* JackPosixSemaphore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C4860D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B35C4880D4731D1000DE7AE /* JackError.h in Headers */, 4B35C4890D4731D1000DE7AE /* JackTime.h in Headers */, 4B35C48A0D4731D1000DE7AE /* JackShmMem.h in Headers */, 4B35C48B0D4731D1000DE7AE /* shm.h in Headers */, 4B35C48D0D4731D1000DE7AE /* JackThread.h in Headers */, 4B35C48E0D4731D1000DE7AE /* JackActivationCount.h in Headers */, 4B35C48F0D4731D1000DE7AE /* JackChannel.h in Headers */, 4B35C4900D4731D1000DE7AE /* JackGraphManager.h in Headers */, 4B35C4910D4731D1000DE7AE /* JackPort.h in Headers */, 4B35C4920D4731D1000DE7AE /* JackClientInterface.h in Headers */, 4B35C4930D4731D1000DE7AE /* JackClientControl.h in Headers */, 4B35C4940D4731D1000DE7AE /* JackClient.h in Headers */, 4B35C4950D4731D1000DE7AE /* JackInternalClient.h in Headers */, 4B35C4960D4731D1000DE7AE /* JackConnectionManager.h in Headers */, 4B35C4970D4731D1000DE7AE /* JackFrameTimer.h in Headers */, 4B35C4990D4731D1000DE7AE /* JackMachSemaphore.h in Headers */, 4B35C49A0D4731D1000DE7AE /* JackGlobals.h in Headers */, 4B35C49B0D4731D1000DE7AE /* JackMachThread.h in Headers */, 4B35C4A00D4731D1000DE7AE /* JackSynchro.h in Headers */, 4B35C4A10D4731D1000DE7AE /* JackAudioDriver.h in Headers */, 4B35C4A20D4731D1000DE7AE /* JackFreewheelDriver.h in Headers */, 4B35C4A30D4731D1000DE7AE /* JackThreadedDriver.h in Headers */, 4B35C4A40D4731D1000DE7AE /* JackDriver.h in Headers */, 4B35C4A50D4731D1000DE7AE /* driver_interface.h in Headers */, 4B35C4A70D4731D1000DE7AE /* JackDriverLoader.h in Headers */, 4B35C4A90D4731D1000DE7AE /* JackEngine.h in Headers */, 4B35C4AA0D4731D1000DE7AE /* JackExternalClient.h in Headers */, 4B35C4AB0D4731D1000DE7AE /* JackServer.h in Headers */, 4B35C4B20D4731D1000DE7AE /* JackConstants.h in Headers */, 4B35C4B30D4731D1000DE7AE /* JackTransportEngine.h in Headers */, 4B35C4B40D4731D1000DE7AE /* JackServerGlobals.h in Headers */, 4B35C4B50D4731D1000DE7AE /* timestamps.h in Headers */, 4B35C4B60D4731D1000DE7AE /* jack.h in Headers */, 4B35C4B70D4731D1000DE7AE /* intclient.h in Headers */, 4B35C4B80D4731D1000DE7AE /* ringbuffer.h in Headers */, 4B35C4B90D4731D1000DE7AE /* statistics.h in Headers */, 4B35C4BA0D4731D1000DE7AE /* thread.h in Headers */, 4B35C4BB0D4731D1000DE7AE /* transport.h in Headers */, 4B35C4BC0D4731D1000DE7AE /* types.h in Headers */, 4B35C4BD0D4731D1000DE7AE /* JackPortType.h in Headers */, 4B35C4BE0D4731D1000DE7AE /* JackMidiPort.h in Headers */, 4B35C4BF0D4731D1000DE7AE /* midiport.h in Headers */, 4B35C4C00D4731D1000DE7AE /* JackDebugClient.h in Headers */, 4B35C4C10D4731D1000DE7AE /* JackTools.h in Headers */, BA222ADB0DC88269001A17F4 /* JackNetTool.h in Headers */, 4B9A26060DBF8584006E9FBC /* jslist.h in Headers */, 4B4F9C930DC20C0400706CB0 /* JackMessageBuffer.h in Headers */, 4B4CA9770E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */, 4B4E9AFD0E5F1090000A3278 /* JackControlAPI.h in Headers */, 4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */, 4BBAE4120F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */, 4BF339220F8B873E0080FB5B /* JackMidiDriver.h in Headers */, 4BDCDBD21001FD0200B15929 /* JackWaitThreadedDriver.h in Headers */, 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */, 4B88D04311298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04411298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA5A113C6CB80076717C /* JackNetInterface.h in Headers */, 4BC2CA5C113C6CC00076717C /* JackNetUnixSocket.h in Headers */, 4B8A38A8117B80DA00664E07 /* JackSocket.h in Headers */, 4B8A38AD117B810A00664E07 /* JackSocketNotifyChannel.h in Headers */, 4B8A38B0117B812500664E07 /* JackSocketServerChannel.h in Headers */, 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */, 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */, 4B193995133F321500547810 /* JackFilters.h in Headers */, 4B97B6611344B49500794F57 /* JackMidiAsyncQueue.h in Headers */, 4B97B6631344B4A800794F57 /* JackMidiAsyncWaitQueue.h in Headers */, 4B97B6651344B4B500794F57 /* JackMidiBufferReadQueue.h in Headers */, 4B97B6671344B4C700794F57 /* JackMidiBufferWriteQueue.h in Headers */, 4B97B66F1344B4DC00794F57 /* JackMidiReadQueue.h in Headers */, 4B97B6711344B4EA00794F57 /* JackMidiReceiveQueue.h in Headers */, 4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */, 4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */, 4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */, 4B21795213E2EEA60095B3E5 /* JackTimedDriver.h in Headers */, 4B49D44A14865F22003390F8 /* net.h in Headers */, 4B49D44B14865F22003390F8 /* session.h in Headers */, 4B1499F114BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, 4B90669B14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, 4BB4215714D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */, 4BB4215914D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */, 4B4C3B6D1BC2FFC70004CC35 /* JackPosixSemaphore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C50B0D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5170D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5230D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C52F0D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C53B0D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5470D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5550D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5610D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C56D0D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5790D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5890D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C59D0D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5A90D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5B50D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5C10D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5CD0D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5D90D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5DA0D4731D2000DE7AE /* JackError.h in Headers */, 4B35C5DB0D4731D2000DE7AE /* JackConstants.h in Headers */, 4B4F9D830DC2178F00706CB0 /* JackMessageBuffer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5ED0D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6010D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6150D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BA4ADB50E87AB2600F26C85 /* JackCoreAudioDriver.h in Headers */, 4BAA150614F04FB600402512 /* JackAC3Encoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6200D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C62B0D4731D2000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B35C62C0D4731D2000DE7AE /* JackDummyDriver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6360D4731D3000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363DCF0DEB02F6001F72D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363E110DEB03C5001F72D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363E450DEB0775001F72D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363EE00DEB091C001F72D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F150DEB0A6A001F72D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F2C0DEB0BD1001F72D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F690DEB0D4E001F72D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B3811561326878E00C61B14 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B38118E1326884E00C61B14 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B43A8B110145F6F00E52943 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B43A8CB1014605000E52943 /* JackLoopbackDriver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B43A8DE1014615800E52943 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B43A8DF1014615800E52943 /* JackLoopbackDriver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B47AC8110B5890100469C67 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B47AC8310B5890100469C67 /* JackError.h in Headers */, 4B47AC8410B5890100469C67 /* JackTime.h in Headers */, 4B47AC8510B5890100469C67 /* JackShmMem.h in Headers */, 4B47AC8610B5890100469C67 /* shm.h in Headers */, 4B47AC8710B5890100469C67 /* JackThread.h in Headers */, 4B47AC8810B5890100469C67 /* JackActivationCount.h in Headers */, 4B47AC8910B5890100469C67 /* JackChannel.h in Headers */, 4B47AC8A10B5890100469C67 /* JackGraphManager.h in Headers */, 4B47AC8B10B5890100469C67 /* JackPort.h in Headers */, 4B47AC8C10B5890100469C67 /* JackClientInterface.h in Headers */, 4B47AC8D10B5890100469C67 /* JackClientControl.h in Headers */, 4B47AC8E10B5890100469C67 /* JackClient.h in Headers */, 4B47AC8F10B5890100469C67 /* JackInternalClient.h in Headers */, 4B47AC9010B5890100469C67 /* JackLibGlobals.h in Headers */, 4B47AC9110B5890100469C67 /* JackLibClient.h in Headers */, 4B47AC9210B5890100469C67 /* JackConnectionManager.h in Headers */, 4B47AC9310B5890100469C67 /* JackFrameTimer.h in Headers */, 4B47AC9410B5890100469C67 /* JackMachSemaphore.h in Headers */, 4B47AC9510B5890100469C67 /* JackGlobals.h in Headers */, 4B47AC9610B5890100469C67 /* JackMachThread.h in Headers */, 4B47AC9810B5890100469C67 /* JackSynchro.h in Headers */, 4B47AC9910B5890100469C67 /* JackDebugClient.h in Headers */, 4B47AC9A10B5890100469C67 /* JackConstants.h in Headers */, 4B47AC9B10B5890100469C67 /* JackTransportEngine.h in Headers */, 4B47AC9C10B5890100469C67 /* timestamps.h in Headers */, 4B47AC9D10B5890100469C67 /* intclient.h in Headers */, 4B47AC9E10B5890100469C67 /* jack.h in Headers */, 4B47AC9F10B5890100469C67 /* ringbuffer.h in Headers */, 4B47ACA010B5890100469C67 /* statistics.h in Headers */, 4B47ACA110B5890100469C67 /* thread.h in Headers */, 4B47ACA210B5890100469C67 /* transport.h in Headers */, 4B47ACA310B5890100469C67 /* types.h in Headers */, 4B47ACA410B5890100469C67 /* JackPortType.h in Headers */, 4B47ACA510B5890100469C67 /* JackMidiPort.h in Headers */, 4B47ACA610B5890100469C67 /* midiport.h in Headers */, 4B47ACA710B5890100469C67 /* JackTools.h in Headers */, 4B47ACA810B5890100469C67 /* jslist.h in Headers */, 4B47ACA910B5890100469C67 /* JackMessageBuffer.h in Headers */, 4B47ACAA10B5890100469C67 /* JackPosixThread.h in Headers */, 4B88D04111298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04211298BEE007A87C1 /* weakmacros.h in Headers */, 4B5160A913215EBF00BB7DCB /* systemdeps.h in Headers */, 4B193994133F321500547810 /* JackFilters.h in Headers */, 4B49D44814865F22003390F8 /* net.h in Headers */, 4B49D44914865F22003390F8 /* session.h in Headers */, 4B1499F914BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, 4BB4215414D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */, 4BB4215614D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */, 4B4C3B6B1BC2FFB50004CC35 /* JackPosixSemaphore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B5A1BB20CD1CB9E0005BF74 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B5A1BD10CD1CCE10005BF74 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B5E08C00E5B66EE00BEE4E0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B5E08C30E5B66EE00BEE4E0 /* JackAudioAdapterInterface.h in Headers */, 4B5E08C60E5B66EE00BEE4E0 /* JackLibSampleRateResampler.h in Headers */, 4B5E08E20E5B676D00BEE4E0 /* JackNetAdapter.h in Headers */, 4B5E08EF0E5B680200BEE4E0 /* JackAudioAdapter.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B6654EE127C34AE00753A79 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699BA8097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699C01097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B699C03097D421600A18468 /* JackError.h in Headers */, 4B699C04097D421600A18468 /* JackTime.h in Headers */, 4B699C05097D421600A18468 /* JackShmMem.h in Headers */, 4B699C06097D421600A18468 /* shm.h in Headers */, 4B699C08097D421600A18468 /* JackThread.h in Headers */, 4B699C09097D421600A18468 /* JackActivationCount.h in Headers */, 4B699C0A097D421600A18468 /* JackChannel.h in Headers */, 4B699C0B097D421600A18468 /* JackGraphManager.h in Headers */, 4B699C0C097D421600A18468 /* JackPort.h in Headers */, 4B699C0D097D421600A18468 /* JackClientInterface.h in Headers */, 4B699C0E097D421600A18468 /* JackClientControl.h in Headers */, 4B699C0F097D421600A18468 /* JackClient.h in Headers */, 4B699C10097D421600A18468 /* JackInternalClient.h in Headers */, 4B699C11097D421600A18468 /* JackLibGlobals.h in Headers */, 4B699C12097D421600A18468 /* JackLibClient.h in Headers */, 4B699C13097D421600A18468 /* JackConnectionManager.h in Headers */, 4B699C14097D421600A18468 /* JackFrameTimer.h in Headers */, 4B699C16097D421600A18468 /* JackMachSemaphore.h in Headers */, 4B699C17097D421600A18468 /* JackGlobals.h in Headers */, 4B699C18097D421600A18468 /* JackMachThread.h in Headers */, 4B699C20097D421600A18468 /* JackSynchro.h in Headers */, 4B699C21097D421600A18468 /* JackDebugClient.h in Headers */, 4B699C22097D421600A18468 /* JackConstants.h in Headers */, 4BF520590CB8D1010037470E /* timestamps.h in Headers */, 4B6C73800CC60A7F001AFFD4 /* intclient.h in Headers */, 4B6C73810CC60A7F001AFFD4 /* jack.h in Headers */, 4B6C73820CC60A7F001AFFD4 /* ringbuffer.h in Headers */, 4B6C73830CC60A80001AFFD4 /* statistics.h in Headers */, 4B6C73840CC60A80001AFFD4 /* thread.h in Headers */, 4B6C73850CC60A81001AFFD4 /* transport.h in Headers */, 4BE3225A0CC611EF00AFA640 /* types.h in Headers */, 4BAB95B90B9E20B800A0C723 /* JackPortType.h in Headers */, 4B80D7E80BA0D17400F035BB /* JackMidiPort.h in Headers */, 4B6B9EF60CD095930051EE5A /* midiport.h in Headers */, 4BE4CC020CDA153500CCF5BB /* JackTools.h in Headers */, 4B9A26010DBF8584006E9FBC /* jslist.h in Headers */, 4B4F9C8F0DC20C0400706CB0 /* JackMessageBuffer.h in Headers */, 4BB9D4B30E2610B300351653 /* JackTransportEngine.h in Headers */, 4BC3B6A50E703B2E0066E42F /* JackPosixThread.h in Headers */, 4B94334A10A5E666002A187F /* systemdeps.h in Headers */, 4B88D03B11298BEE007A87C1 /* weakjack.h in Headers */, 4B88D03C11298BEE007A87C1 /* weakmacros.h in Headers */, 4B2209ED12F6BC2200E5DC26 /* JackSocket.h in Headers */, 4B2209EF12F6BC2500E5DC26 /* JackSocketClientChannel.h in Headers */, 4B193991133F321500547810 /* JackFilters.h in Headers */, 4B49D44414865F22003390F8 /* net.h in Headers */, 4B49D44514865F22003390F8 /* session.h in Headers */, 4B1499F514BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, 4BB4214B14D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */, 4BB4214D14D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699C4D097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B699C4F097D421600A18468 /* JackError.h in Headers */, 4B699C50097D421600A18468 /* JackTime.h in Headers */, 4B699C51097D421600A18468 /* JackShmMem.h in Headers */, 4B699C52097D421600A18468 /* shm.h in Headers */, 4B699C54097D421600A18468 /* JackThread.h in Headers */, 4B699C55097D421600A18468 /* JackActivationCount.h in Headers */, 4B699C56097D421600A18468 /* JackChannel.h in Headers */, 4B699C57097D421600A18468 /* JackGraphManager.h in Headers */, 4B699C58097D421600A18468 /* JackPort.h in Headers */, 4B699C59097D421600A18468 /* JackClientInterface.h in Headers */, 4B699C5A097D421600A18468 /* JackClientControl.h in Headers */, 4B699C5B097D421600A18468 /* JackClient.h in Headers */, 4B699C5C097D421600A18468 /* JackInternalClient.h in Headers */, 4B699C5D097D421600A18468 /* JackConnectionManager.h in Headers */, 4B699C5E097D421600A18468 /* JackFrameTimer.h in Headers */, 4B699C60097D421600A18468 /* JackMachSemaphore.h in Headers */, 4B699C61097D421600A18468 /* JackGlobals.h in Headers */, 4B699C62097D421600A18468 /* JackMachThread.h in Headers */, 4B699C68097D421600A18468 /* JackSynchro.h in Headers */, 4B699C69097D421600A18468 /* JackAudioDriver.h in Headers */, 4B699C6A097D421600A18468 /* JackFreewheelDriver.h in Headers */, 4B699C6B097D421600A18468 /* JackThreadedDriver.h in Headers */, 4B699C6C097D421600A18468 /* JackDriver.h in Headers */, 4B699C6D097D421600A18468 /* driver_interface.h in Headers */, 4B699C6F097D421600A18468 /* JackDriverLoader.h in Headers */, 4B699C71097D421600A18468 /* JackEngine.h in Headers */, 4B699C73097D421600A18468 /* JackExternalClient.h in Headers */, 4B699C74097D421600A18468 /* JackServer.h in Headers */, 4B699C7B097D421600A18468 /* JackConstants.h in Headers */, 4BD4B4D809BACD9600750C0F /* JackTransportEngine.h in Headers */, 4BC2168E0A444BED00BDA09F /* JackServerGlobals.h in Headers */, 4BF5205A0CB8D1010037470E /* timestamps.h in Headers */, 4B6C73860CC60A83001AFFD4 /* jack.h in Headers */, 4B6C73870CC60A84001AFFD4 /* intclient.h in Headers */, 4B6C73880CC60A84001AFFD4 /* ringbuffer.h in Headers */, 4B6C73890CC60A85001AFFD4 /* statistics.h in Headers */, 4B6C738A0CC60A85001AFFD4 /* thread.h in Headers */, 4B6C738B0CC60A86001AFFD4 /* transport.h in Headers */, 4BE3225B0CC611F500AFA640 /* types.h in Headers */, 4BAB95BB0B9E20B800A0C723 /* JackPortType.h in Headers */, 4B80D7EB0BA0D17400F035BB /* JackMidiPort.h in Headers */, 4B6B9EF70CD095970051EE5A /* midiport.h in Headers */, 4B5DB9840CD2429B00EBA5EE /* JackDebugClient.h in Headers */, 4BE4CC040CDA153500CCF5BB /* JackTools.h in Headers */, BA222AD90DC88269001A17F4 /* JackNetTool.h in Headers */, BA047C760E14E79D0041F3B6 /* JackNetSocket.h in Headers */, 4B95BCAE0D913073000F7695 /* control.h in Headers */, 4B9A26020DBF8584006E9FBC /* jslist.h in Headers */, 4B4F9C8D0DC20C0400706CB0 /* JackMessageBuffer.h in Headers */, 4B5F253E0DEE9B8F0041E486 /* JackLockedEngine.h in Headers */, 4BBC93BB0DF9736C002DF220 /* JackWaitThreadedDriver.h in Headers */, 4B4CA9750E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */, 4B4E9AFB0E5F1090000A3278 /* JackControlAPI.h in Headers */, 4BC3B6A70E703B2E0066E42F /* JackPosixThread.h in Headers */, 4BF2841B0F31B4BC00B05BE3 /* JackArgParser.h in Headers */, 4BBAE4100F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */, 4BF339240F8B873E0080FB5B /* JackMidiDriver.h in Headers */, 4B94334B10A5E666002A187F /* systemdeps.h in Headers */, 4B88D03D11298BEE007A87C1 /* weakjack.h in Headers */, 4B88D03E11298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA56113C6C940076717C /* JackNetInterface.h in Headers */, 4BC2CA58113C6C9C0076717C /* JackNetUnixSocket.h in Headers */, 4B2209E212F6BBF400E5DC26 /* JackSocketServerChannel.h in Headers */, 4B2209E412F6BBF600E5DC26 /* JackSocketServerNotifyChannel.h in Headers */, 4B2209E712F6BC0300E5DC26 /* JackSocket.h in Headers */, 4B2209EA12F6BC1600E5DC26 /* JackSocketNotifyChannel.h in Headers */, 4B193992133F321500547810 /* JackFilters.h in Headers */, 4B97B6391344B3C300794F57 /* JackMidiAsyncQueue.h in Headers */, 4B97B63D1344B3EC00794F57 /* JackMidiAsyncWaitQueue.h in Headers */, 4B97B6411344B40C00794F57 /* JackMidiBufferReadQueue.h in Headers */, 4B97B6541344B42400794F57 /* JackMidiBufferWriteQueue.h in Headers */, 4B97B6561344B43600794F57 /* JackMidiReadQueue.h in Headers */, 4B97B6591344B44800794F57 /* JackMidiReceiveQueue.h in Headers */, 4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */, 4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */, 4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */, 4B21795013E2EEA60095B3E5 /* JackTimedDriver.h in Headers */, 4B49D44214865F22003390F8 /* net.h in Headers */, 4B49D44314865F22003390F8 /* session.h in Headers */, 4B1499FB14BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, 4B90669F14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, 4BB4214E14D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */, 4BB4215014D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CB2097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CC2097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CD2097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CE2097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CF4097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D04097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D14097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D28097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D40097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D50097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D68097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D80097D421700A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D98097D421700A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BE5FECE0E725C090020B576 /* JackCoreAudioDriver.h in Headers */, 4BAA150414F04FB600402512 /* JackAC3Encoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699DA7097D421700A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B699DA8097D421700A18468 /* JackDummyDriver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B8692831371DB4700D2D11B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B8692FA1371DC6300D2D11B /* JackAudioAdapterInterface.h in Headers */, 4B8692FD1371DC8A00D2D11B /* JackGlobals.h in Headers */, 4B86930D1371DCB000D2D11B /* JackMachThread.h in Headers */, 4B8693181371DD2A00D2D11B /* JackNetInterface.h in Headers */, 4B86931A1371DD4400D2D11B /* JackNetTool.h in Headers */, 4B86934E1371DEBD00D2D11B /* JackLibSampleRateResampler.h in Headers */, 4B49D44E14865F22003390F8 /* net.h in Headers */, 4B49D44F14865F22003390F8 /* session.h in Headers */, 4BF1007D15135D8800B88F80 /* JackPosixMutex.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B8F16DC13290DC80002AD73 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B8F16E913290E0E0002AD73 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B978DB20A31CF4A009E2DD1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BBB00D40E72614F0018AB1B /* JackPortAudioDevices.h in Headers */, 4BBB00D60E72614F0018AB1B /* JackPortAudioDriver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BA3393410B2E36800190E3B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BA3393610B2E36800190E3B /* JackError.h in Headers */, 4BA3393710B2E36800190E3B /* JackTime.h in Headers */, 4BA3393810B2E36800190E3B /* JackShmMem.h in Headers */, 4BA3393910B2E36800190E3B /* shm.h in Headers */, 4BA3393A10B2E36800190E3B /* JackThread.h in Headers */, 4BA3393B10B2E36800190E3B /* JackActivationCount.h in Headers */, 4BA3393C10B2E36800190E3B /* JackChannel.h in Headers */, 4BA3393D10B2E36800190E3B /* JackGraphManager.h in Headers */, 4BA3393E10B2E36800190E3B /* JackPort.h in Headers */, 4BA3393F10B2E36800190E3B /* JackClientInterface.h in Headers */, 4BA3394010B2E36800190E3B /* JackClientControl.h in Headers */, 4BA3394110B2E36800190E3B /* JackClient.h in Headers */, 4BA3394210B2E36800190E3B /* JackInternalClient.h in Headers */, 4BA3394310B2E36800190E3B /* JackConnectionManager.h in Headers */, 4BA3394410B2E36800190E3B /* JackFrameTimer.h in Headers */, 4BA3394510B2E36800190E3B /* JackMachSemaphore.h in Headers */, 4BA3394610B2E36800190E3B /* JackGlobals.h in Headers */, 4BA3394710B2E36800190E3B /* JackMachThread.h in Headers */, 4BA3394810B2E36800190E3B /* JackSynchro.h in Headers */, 4BA3394910B2E36800190E3B /* JackAudioDriver.h in Headers */, 4BA3394A10B2E36800190E3B /* JackFreewheelDriver.h in Headers */, 4BA3394B10B2E36800190E3B /* JackThreadedDriver.h in Headers */, 4BA3394C10B2E36800190E3B /* JackDriver.h in Headers */, 4BA3394D10B2E36800190E3B /* driver_interface.h in Headers */, 4BA3394E10B2E36800190E3B /* JackDriverLoader.h in Headers */, 4BA3394F10B2E36800190E3B /* JackEngine.h in Headers */, 4BA3395010B2E36800190E3B /* JackExternalClient.h in Headers */, 4BA3395110B2E36800190E3B /* JackServer.h in Headers */, 4BA3395510B2E36800190E3B /* JackConstants.h in Headers */, 4BA3395610B2E36800190E3B /* JackTransportEngine.h in Headers */, 4BA3395710B2E36800190E3B /* JackServerGlobals.h in Headers */, 4BA3395810B2E36800190E3B /* timestamps.h in Headers */, 4BA3395910B2E36800190E3B /* jack.h in Headers */, 4BA3395A10B2E36800190E3B /* intclient.h in Headers */, 4BA3395B10B2E36800190E3B /* ringbuffer.h in Headers */, 4BA3395C10B2E36800190E3B /* statistics.h in Headers */, 4BA3395D10B2E36800190E3B /* thread.h in Headers */, 4BA3395E10B2E36800190E3B /* transport.h in Headers */, 4BA3395F10B2E36800190E3B /* types.h in Headers */, 4BA3396010B2E36800190E3B /* JackPortType.h in Headers */, 4BA3396110B2E36800190E3B /* JackMidiPort.h in Headers */, 4BA3396210B2E36800190E3B /* midiport.h in Headers */, 4BA3396310B2E36800190E3B /* JackDebugClient.h in Headers */, 4BA3396410B2E36800190E3B /* JackTools.h in Headers */, 4BA3396510B2E36800190E3B /* JackNetTool.h in Headers */, 4BA3396610B2E36800190E3B /* jslist.h in Headers */, 4BA3396710B2E36800190E3B /* JackMessageBuffer.h in Headers */, 4BA3396810B2E36800190E3B /* JackRestartThreadedDriver.h in Headers */, 4BA3396910B2E36800190E3B /* JackControlAPI.h in Headers */, 4BA3396A10B2E36800190E3B /* JackPosixThread.h in Headers */, 4BA3396B10B2E36800190E3B /* JackEngineProfiling.h in Headers */, 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */, 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */, 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */, 4B88D04511298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA5E113C6CCA0076717C /* JackNetInterface.h in Headers */, 4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */, 4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */, 4B193996133F321500547810 /* JackFilters.h in Headers */, 4B6FE13A13DDABE000B4B943 /* JackSocketServerNotifyChannel.h in Headers */, 4B6FE13C13DDABF100B4B943 /* JackSocketServerChannel.h in Headers */, 4B6FE13E13DDAC0500B4B943 /* JackSocketNotifyChannel.h in Headers */, 4B6FE14513DDAC4C00B4B943 /* JackSocket.h in Headers */, 4B6FE14E13DDACD200B4B943 /* JackMidiAsyncQueue.h in Headers */, 4B6FE15413DDACF300B4B943 /* JackMidiBufferWriteQueue.h in Headers */, 4B6FE15B13DDAD3D00B4B943 /* JackMidiWriteQueue.h in Headers */, 4B6FE15D13DDAD4E00B4B943 /* JackMidiUtil.h in Headers */, 4B6FE15F13DDAD5900B4B943 /* JackMidiSendQueue.h in Headers */, 4B6FE16113DDAD6600B4B943 /* JackMidiReceiveQueue.h in Headers */, 4B6FE16313DDAD7700B4B943 /* JackMidiReadQueue.h in Headers */, 4B6FE16513DDAD8800B4B943 /* JackMidiBufferReadQueue.h in Headers */, 4B6FE16713DDAD9700B4B943 /* JackMidiAsyncWaitQueue.h in Headers */, 4B21795413E2EEA60095B3E5 /* JackTimedDriver.h in Headers */, 4B49D44C14865F22003390F8 /* net.h in Headers */, 4B49D44D14865F22003390F8 /* session.h in Headers */, 4B1499F314BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, 4B90669D14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, 4BB4215A14D2C0A700A1CAE1 /* JackPosixMutex.h in Headers */, 4BB4215C14D2C0A700A1CAE1 /* JackPosixProcessSync.h in Headers */, 4B4C3B6F1BC2FFE00004CC35 /* JackPosixSemaphore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BA692A70CBE4BC700EAD520 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA692CB0CBE4C9000EAD520 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA7FEBA0D8E76270017FF73 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BD623EE0CBCF0F000DE782F /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDB941001FB9C00B15929 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDB951001FB9C00B15929 /* JackCoreMidiDriver.h in Headers */, 4B370A35133DD7E300237B68 /* JackCoreMidiInputPort.h in Headers */, 4B370A37133DD7E300237B68 /* JackCoreMidiOutputPort.h in Headers */, 4B370A39133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.h in Headers */, 4B370A3B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h in Headers */, 4B370A3D133DD7E300237B68 /* JackCoreMidiPort.h in Headers */, 4B370A3F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, 4B370A41133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, 4B370A43133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBB81001FCC000B15929 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDBB91001FCC000B15929 /* JackNetDriver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBD81001FD2D00B15929 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDBD91001FD2D00B15929 /* JackNetManager.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBED1001FD7300B15929 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDBEE1001FD7300B15929 /* JackAudioAdapter.h in Headers */, 4BDCDBEF1001FD7300B15929 /* JackAudioAdapterInterface.h in Headers */, 4BDCDBF11001FD7300B15929 /* JackLibSampleRateResampler.h in Headers */, 4BDCDBF21001FD7300B15929 /* JackCoreAudioAdapter.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDC101001FDE300B15929 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDC111001FDE300B15929 /* JackAudioAdapterInterface.h in Headers */, 4BDCDC131001FDE300B15929 /* JackLibSampleRateResampler.h in Headers */, 4BDCDC141001FDE300B15929 /* JackNetAdapter.h in Headers */, 4BDCDC161001FDE300B15929 /* JackAudioAdapter.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BE6C6920A3E096F005A203A /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BE99D270AD7A04800C59091 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BF339030F8B864B0080FB5B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4BF3391A0F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */, 4B370A25133DD7E300237B68 /* JackCoreMidiInputPort.h in Headers */, 4B370A27133DD7E300237B68 /* JackCoreMidiOutputPort.h in Headers */, 4B370A29133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.h in Headers */, 4B370A2B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h in Headers */, 4B370A2D133DD7E300237B68 /* JackCoreMidiPort.h in Headers */, 4B370A2F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, 4B370A31133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, 4B370A33133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA5E8C0DEC4D9C00FA4CDB /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82830DF6A9E40087B4E1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82960DF6A9E40087B4E1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82A20DF6A9E40087B4E1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82AE0DF6A9E40087B4E1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82BA0DF6A9E40087B4E1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82C60DF6A9E40087B4E1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA99990AAAF3B0009E916C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; BA222AC60DC88132001A17F4 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( BA222ADF0DC882A5001A17F4 /* JackNetDriver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; BA222AE10DC882DB001A17F4 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( BA222AEE0DC883B3001A17F4 /* JackNetManager.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 4B0A28DC0D52073D002EFF74 /* jack_thread_wait */ = { isa = PBXNativeTarget; buildConfigurationList = 4B0A28E20D52073D002EFF74 /* Build configuration list for PBXNativeTarget "jack_thread_wait" */; buildPhases = ( 4B0A28DD0D52073D002EFF74 /* Headers */, 4B0A28DE0D52073D002EFF74 /* Sources */, 4B0A28E00D52073D002EFF74 /* Frameworks */, 4B0A28E10D52073D002EFF74 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = jack_thread_wait; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B0A28E60D52073D002EFF74 /* jack_thread_wait */; productType = "com.apple.product-type.tool"; }; 4B0A29230D52108E002EFF74 /* jack_thread_wait 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B0A29290D52108E002EFF74 /* Build configuration list for PBXNativeTarget "jack_thread_wait 64 bits" */; buildPhases = ( 4B0A29240D52108E002EFF74 /* Headers */, 4B0A29250D52108E002EFF74 /* Sources */, 4B0A29270D52108E002EFF74 /* Frameworks */, 4B0A29280D52108E002EFF74 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_thread_wait 64 bits"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B0A292D0D52108E002EFF74 /* jack_thread_wait */; productType = "com.apple.product-type.tool"; }; 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B19B2FC0E23620F00DD4A82 /* Build configuration list for PBXNativeTarget "audioadapter Universal" */; buildPhases = ( 4B19B2F70E23620F00DD4A82 /* Headers */, 4B19B2F90E23620F00DD4A82 /* Sources */, 4B19B2FB0E23620F00DD4A82 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "audioadapter Universal"; productName = jack_coreaudio; productReference = 4B19B3000E23620F00DD4A82 /* audioadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B2021DC133A9BA40019E213 /* jack_midi_latency 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B2021E2133A9BA40019E213 /* Build configuration list for PBXNativeTarget "jack_midi_latency 64 bits" */; buildPhases = ( 4B2021DD133A9BA40019E213 /* Headers */, 4B2021DE133A9BA40019E213 /* Sources */, 4B2021E0133A9BA40019E213 /* Frameworks */, 4B2021E1133A9BA40019E213 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_midi_latency 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B2021E6133A9BA40019E213 /* jack_midi_latency_test */; productType = "com.apple.product-type.tool"; }; 4B3224D710A3156800838A8E /* jack_netone Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B3224E110A3156800838A8E /* Build configuration list for PBXNativeTarget "jack_netone Universal" */; buildPhases = ( 4B3224D810A3156800838A8E /* Headers */, 4B3224DC10A3156800838A8E /* Sources */, 4B3224E010A3156800838A8E /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_netone Universal"; productName = jack_coreaudio; productReference = 4B3224E510A3156800838A8E /* jack_netone.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B32251D10A316B200838A8E /* jack_netone 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B32252710A316B200838A8E /* Build configuration list for PBXNativeTarget "jack_netone 64 bits" */; buildPhases = ( 4B32251E10A316B200838A8E /* Headers */, 4B32252210A316B200838A8E /* Sources */, 4B32252610A316B200838A8E /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_netone 64 bits"; productName = jack_coreaudio; productReference = 4B32252B10A316B200838A8E /* jack_netone.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B32255710A3187800838A8E /* jack_netsource Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B32255D10A3187800838A8E /* Build configuration list for PBXNativeTarget "jack_netsource Universal" */; buildPhases = ( 4B32255810A3187800838A8E /* Headers */, 4B32255910A3187800838A8E /* Sources */, 4B32255B10A3187800838A8E /* Frameworks */, 4B32255C10A3187800838A8E /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_netsource Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B32256110A3187800838A8E /* jack_netsource */; productType = "com.apple.product-type.tool"; }; 4B32257110A3190C00838A8E /* jack_netsource 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B32257710A3190C00838A8E /* Build configuration list for PBXNativeTarget "jack_netsource 64 bits" */; buildPhases = ( 4B32257210A3190C00838A8E /* Headers */, 4B32257310A3190C00838A8E /* Sources */, 4B32257510A3190C00838A8E /* Frameworks */, 4B32257610A3190C00838A8E /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_netsource 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B32257B10A3190C00838A8E /* jack_netsource */; productType = "com.apple.product-type.tool"; }; 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C4210D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jackdmp framework 64bits" */; buildPhases = ( 4B35C41C0D4731D1000DE7AE /* Headers */, 4B35C41D0D4731D1000DE7AE /* Sources */, 4B35C41F0D4731D1000DE7AE /* Frameworks */, 4B35C4200D4731D1000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jackdmp framework 64bits"; productInstallPath = /usr/local/bin; productName = TestMacEngine; productReference = 4B35C4250D4731D1000DE7AE /* jackdmp */; productType = "com.apple.product-type.tool"; }; 4B35C4270D4731D1000DE7AE /* Jackmp.framework 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C47F0D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "Jackmp.framework 64 bits" */; buildPhases = ( 4B35C4280D4731D1000DE7AE /* Headers */, 4B35C4560D4731D1000DE7AE /* Resources */, 4B35C4570D4731D1000DE7AE /* Sources */, 4B35C47D0D4731D1000DE7AE /* Rez */, 4B35C47E0D4731D1000DE7AE /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Jackmp.framework 64 bits"; productName = Jack; productReference = 4B35C4830D4731D1000DE7AE /* Jackmp.framework */; productType = "com.apple.product-type.framework"; }; 4B35C4850D4731D1000DE7AE /* Jackservermp.framework 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C4F80D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "Jackservermp.framework 64 bits" */; buildPhases = ( 4B35C4860D4731D1000DE7AE /* Headers */, 4B35C4C20D4731D1000DE7AE /* Resources */, 4B35C4C30D4731D1000DE7AE /* Sources */, 4B35C4F60D4731D1000DE7AE /* Rez */, 4B35C4F70D4731D1000DE7AE /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Jackservermp.framework 64 bits"; productName = Jack; productReference = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; productType = "com.apple.product-type.framework"; }; 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5100D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_midiseq 64 bits" */; buildPhases = ( 4B35C50B0D4731D1000DE7AE /* Headers */, 4B35C50C0D4731D1000DE7AE /* Sources */, 4B35C50E0D4731D1000DE7AE /* Frameworks */, 4B35C50F0D4731D1000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_midiseq 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B35C5140D4731D1000DE7AE /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4B35C5160D4731D1000DE7AE /* jack_midisine 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C51C0D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_midisine 64 bits" */; buildPhases = ( 4B35C5170D4731D1000DE7AE /* Headers */, 4B35C5180D4731D1000DE7AE /* Sources */, 4B35C51A0D4731D1000DE7AE /* Frameworks */, 4B35C51B0D4731D1000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_midisine 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B35C5200D4731D1000DE7AE /* jack_midisine */; productType = "com.apple.product-type.tool"; }; 4B35C5220D4731D1000DE7AE /* jack_metro 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5280D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_metro 64 bits" */; buildPhases = ( 4B35C5230D4731D1000DE7AE /* Headers */, 4B35C5240D4731D1000DE7AE /* Sources */, 4B35C5260D4731D1000DE7AE /* Frameworks */, 4B35C5270D4731D1000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_metro 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B35C52C0D4731D1000DE7AE /* jack_metro */; productType = "com.apple.product-type.tool"; }; 4B35C52E0D4731D1000DE7AE /* jack_lsp 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5340D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_lsp 64 bits" */; buildPhases = ( 4B35C52F0D4731D1000DE7AE /* Headers */, 4B35C5300D4731D1000DE7AE /* Sources */, 4B35C5320D4731D1000DE7AE /* Frameworks */, 4B35C5330D4731D1000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_lsp 64 bits"; productInstallPath = /usr/local/bin; productName = jack_lsp; productReference = 4B35C5380D4731D1000DE7AE /* jack_lsp */; productType = "com.apple.product-type.tool"; }; 4B35C53A0D4731D1000DE7AE /* jack_connect 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5400D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_connect 64 bits" */; buildPhases = ( 4B35C53B0D4731D1000DE7AE /* Headers */, 4B35C53C0D4731D1000DE7AE /* Sources */, 4B35C53E0D4731D1000DE7AE /* Frameworks */, 4B35C53F0D4731D1000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_connect 64 bits"; productInstallPath = /usr/local/bin; productName = jack_connect; productReference = 4B35C5440D4731D1000DE7AE /* jack_connect */; productType = "com.apple.product-type.tool"; }; 4B35C5460D4731D1000DE7AE /* jack_disconnect 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C54C0D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_disconnect 64 bits" */; buildPhases = ( 4B35C5470D4731D1000DE7AE /* Headers */, 4B35C5480D4731D1000DE7AE /* Sources */, 4B35C54A0D4731D1000DE7AE /* Frameworks */, 4B35C54B0D4731D1000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_disconnect 64 bits"; productInstallPath = /usr/local/bin; productName = jack_disconnect; productReference = 4B35C5500D4731D1000DE7AE /* jack_disconnect */; productType = "com.apple.product-type.tool"; }; 4B35C5520D4731D2000DE7AE /* jack_freewheel 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C55A0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_freewheel 64 bits" */; buildPhases = ( 4B35C5550D4731D2000DE7AE /* Headers */, 4B35C5560D4731D2000DE7AE /* Sources */, 4B35C5580D4731D2000DE7AE /* Frameworks */, 4B35C5590D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( 4B35C5530D4731D2000DE7AE /* PBXTargetDependency */, ); name = "jack_freewheel 64 bits"; productInstallPath = /usr/local/bin; productName = jack_freewheel; productReference = 4B35C55E0D4731D2000DE7AE /* jack_freewheel */; productType = "com.apple.product-type.tool"; }; 4B35C5600D4731D2000DE7AE /* jack_iodelay 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5660D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_iodelay 64 bits" */; buildPhases = ( 4B35C5610D4731D2000DE7AE /* Headers */, 4B35C5620D4731D2000DE7AE /* Sources */, 4B35C5640D4731D2000DE7AE /* Frameworks */, 4B35C5650D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_iodelay 64 bits"; productInstallPath = /usr/local/bin; productName = jack_lsp; productReference = 4B35C56A0D4731D2000DE7AE /* jack_iodelay */; productType = "com.apple.product-type.tool"; }; 4B35C56C0D4731D2000DE7AE /* jack_external_metro 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5720D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_external_metro 64 bits" */; buildPhases = ( 4B35C56D0D4731D2000DE7AE /* Headers */, 4B35C56E0D4731D2000DE7AE /* Sources */, 4B35C5700D4731D2000DE7AE /* Frameworks */, 4B35C5710D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_external_metro 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B35C5760D4731D2000DE7AE /* jack_external_metro */; productType = "com.apple.product-type.tool"; }; 4B35C5780D4731D2000DE7AE /* testAtomic 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5820D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "testAtomic 64 bits" */; buildPhases = ( 4B35C5790D4731D2000DE7AE /* Headers */, 4B35C57C0D4731D2000DE7AE /* Sources */, 4B35C5800D4731D2000DE7AE /* Frameworks */, 4B35C5810D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "testAtomic 64 bits"; productInstallPath = /usr/local/bin; productName = testAtomic; productReference = 4B35C5860D4731D2000DE7AE /* testAtomic */; productType = "com.apple.product-type.tool"; }; 4B35C5880D4731D2000DE7AE /* testSem 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5960D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "testSem 64 bits" */; buildPhases = ( 4B35C5890D4731D2000DE7AE /* Headers */, 4B35C58C0D4731D2000DE7AE /* Sources */, 4B35C5940D4731D2000DE7AE /* Frameworks */, 4B35C5950D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "testSem 64 bits"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B35C59A0D4731D2000DE7AE /* testSem */; productType = "com.apple.product-type.tool"; }; 4B35C59C0D4731D2000DE7AE /* zombie 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5A20D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "zombie 64 bits" */; buildPhases = ( 4B35C59D0D4731D2000DE7AE /* Headers */, 4B35C59E0D4731D2000DE7AE /* Sources */, 4B35C5A00D4731D2000DE7AE /* Frameworks */, 4B35C5A10D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "zombie 64 bits"; productInstallPath = /usr/local/bin; productName = zombie; productReference = 4B35C5A60D4731D2000DE7AE /* zombie */; productType = "com.apple.product-type.tool"; }; 4B35C5A80D4731D2000DE7AE /* jack_test 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5AE0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_test 64 bits" */; buildPhases = ( 4B35C5A90D4731D2000DE7AE /* Headers */, 4B35C5AA0D4731D2000DE7AE /* Sources */, 4B35C5AC0D4731D2000DE7AE /* Frameworks */, 4B35C5AD0D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_test 64 bits"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B35C5B20D4731D2000DE7AE /* jack_test */; productType = "com.apple.product-type.tool"; }; 4B35C5B40D4731D2000DE7AE /* jack_cpu 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5BA0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_cpu 64 bits" */; buildPhases = ( 4B35C5B50D4731D2000DE7AE /* Headers */, 4B35C5B60D4731D2000DE7AE /* Sources */, 4B35C5B80D4731D2000DE7AE /* Frameworks */, 4B35C5B90D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_cpu 64 bits"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B35C5BE0D4731D2000DE7AE /* jack_cpu */; productType = "com.apple.product-type.tool"; }; 4B35C5C00D4731D2000DE7AE /* jack_load 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5C60D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_load 64 bits" */; buildPhases = ( 4B35C5C10D4731D2000DE7AE /* Headers */, 4B35C5C20D4731D2000DE7AE /* Sources */, 4B35C5C40D4731D2000DE7AE /* Frameworks */, 4B35C5C50D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_load 64 bits"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B35C5CA0D4731D2000DE7AE /* jack_load */; productType = "com.apple.product-type.tool"; }; 4B35C5CC0D4731D2000DE7AE /* jack_unload 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5D20D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_unload 64 bits" */; buildPhases = ( 4B35C5CD0D4731D2000DE7AE /* Headers */, 4B35C5CE0D4731D2000DE7AE /* Sources */, 4B35C5D00D4731D2000DE7AE /* Frameworks */, 4B35C5D10D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_unload 64 bits"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B35C5D60D4731D2000DE7AE /* jack_unload */; productType = "com.apple.product-type.tool"; }; 4B35C5D80D4731D2000DE7AE /* synchroServer 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5E60D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "synchroServer 64 bits" */; buildPhases = ( 4B35C5D90D4731D2000DE7AE /* Headers */, 4B35C5DC0D4731D2000DE7AE /* Sources */, 4B35C5E40D4731D2000DE7AE /* Frameworks */, 4B35C5E50D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "synchroServer 64 bits"; productInstallPath = /usr/local/bin; productName = synchroServer; productReference = 4B35C5EA0D4731D2000DE7AE /* synchroServer */; productType = "com.apple.product-type.tool"; }; 4B35C5EC0D4731D2000DE7AE /* synchroClient 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C5FA0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "synchroClient 64 bits" */; buildPhases = ( 4B35C5ED0D4731D2000DE7AE /* Headers */, 4B35C5F00D4731D2000DE7AE /* Sources */, 4B35C5F80D4731D2000DE7AE /* Frameworks */, 4B35C5F90D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "synchroClient 64 bits"; productInstallPath = /usr/local/bin; productName = synchroServer; productReference = 4B35C5FE0D4731D2000DE7AE /* synchroClient */; productType = "com.apple.product-type.tool"; }; 4B35C6000D4731D2000DE7AE /* synchroServerClient 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C60E0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "synchroServerClient 64 bits" */; buildPhases = ( 4B35C6010D4731D2000DE7AE /* Headers */, 4B35C6040D4731D2000DE7AE /* Sources */, 4B35C60C0D4731D2000DE7AE /* Frameworks */, 4B35C60D0D4731D2000DE7AE /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "synchroServerClient 64 bits"; productInstallPath = /usr/local/bin; productName = synchroServer; productReference = 4B35C6120D4731D2000DE7AE /* synchroServerClient */; productType = "com.apple.product-type.tool"; }; 4B35C6140D4731D2000DE7AE /* jack_coreaudio 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C61A0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_coreaudio 64 bits" */; buildPhases = ( 4B35C6150D4731D2000DE7AE /* Headers */, 4B35C6170D4731D2000DE7AE /* Sources */, 4B35C6190D4731D2000DE7AE /* Frameworks */, ); buildRules = ( ); dependencies = ( 4BAA1A7614CA08FE003269AD /* PBXTargetDependency */, ); name = "jack_coreaudio 64 bits"; productName = jack_coreaudio; productReference = 4B35C61E0D4731D2000DE7AE /* jack_coreaudio.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B35C61F0D4731D2000DE7AE /* jack_portaudio 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C6250D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_portaudio 64 bits" */; buildPhases = ( 4B35C6200D4731D2000DE7AE /* Headers */, 4B35C6220D4731D2000DE7AE /* Sources */, 4B35C6240D4731D2000DE7AE /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_portaudio 64 bits"; productName = jack_coreaudio; productReference = 4B35C6290D4731D2000DE7AE /* jack_portaudio.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B35C62A0D4731D2000DE7AE /* jack_dummy 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C6300D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_dummy 64 bits" */; buildPhases = ( 4B35C62B0D4731D2000DE7AE /* Headers */, 4B35C62D0D4731D2000DE7AE /* Sources */, 4B35C62F0D4731D2000DE7AE /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_dummy 64 bits"; productName = jack_coreaudio; productReference = 4B35C6340D4731D2000DE7AE /* jack_dummy.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B35C6350D4731D3000DE7AE /* inprocess 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C63A0D4731D3000DE7AE /* Build configuration list for PBXNativeTarget "inprocess 64 bits" */; buildPhases = ( 4B35C6360D4731D3000DE7AE /* Headers */, 4B35C6370D4731D3000DE7AE /* Sources */, 4B35C6390D4731D3000DE7AE /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "inprocess 64 bits"; productName = jack_coreaudio; productReference = 4B35C63E0D4731D3000DE7AE /* inprocess.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B363DCE0DEB02F6001F72D9 /* jack_alias Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B363DD40DEB02F6001F72D9 /* Build configuration list for PBXNativeTarget "jack_alias Universal" */; buildPhases = ( 4B363DCF0DEB02F6001F72D9 /* Headers */, 4B363DD00DEB02F6001F72D9 /* Sources */, 4B363DD20DEB02F6001F72D9 /* Frameworks */, 4B363DD30DEB02F6001F72D9 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_alias Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B363DD80DEB02F6001F72D9 /* jack_alias */; productType = "com.apple.product-type.tool"; }; 4B363E100DEB03C5001F72D9 /* jack_evmon Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B363E160DEB03C5001F72D9 /* Build configuration list for PBXNativeTarget "jack_evmon Universal" */; buildPhases = ( 4B363E110DEB03C5001F72D9 /* Headers */, 4B363E120DEB03C5001F72D9 /* Sources */, 4B363E140DEB03C5001F72D9 /* Frameworks */, 4B363E150DEB03C5001F72D9 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_evmon Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B363E1A0DEB03C5001F72D9 /* jack_evmon */; productType = "com.apple.product-type.tool"; }; 4B363E440DEB0775001F72D9 /* jack_bufsize Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B363E4A0DEB0775001F72D9 /* Build configuration list for PBXNativeTarget "jack_bufsize Universal" */; buildPhases = ( 4B363E450DEB0775001F72D9 /* Headers */, 4B363E460DEB0775001F72D9 /* Sources */, 4B363E480DEB0775001F72D9 /* Frameworks */, 4B363E490DEB0775001F72D9 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_bufsize Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B363E4E0DEB0775001F72D9 /* jack_bufsize */; productType = "com.apple.product-type.tool"; }; 4B363EDF0DEB091C001F72D9 /* jack_rec Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B363EE50DEB091C001F72D9 /* Build configuration list for PBXNativeTarget "jack_rec Universal" */; buildPhases = ( 4B363EE00DEB091C001F72D9 /* Headers */, 4B363EE10DEB091C001F72D9 /* Sources */, 4B363EE30DEB091C001F72D9 /* Frameworks */, 4B363EE40DEB091C001F72D9 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_rec Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B363EE90DEB091C001F72D9 /* jack_rec */; productType = "com.apple.product-type.tool"; }; 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B363F1A0DEB0A6A001F72D9 /* Build configuration list for PBXNativeTarget "jack_monitor_client Universal" */; buildPhases = ( 4B363F150DEB0A6A001F72D9 /* Headers */, 4B363F160DEB0A6A001F72D9 /* Sources */, 4B363F180DEB0A6A001F72D9 /* Frameworks */, 4B363F190DEB0A6A001F72D9 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_monitor_client Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */; productType = "com.apple.product-type.tool"; }; 4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B363F310DEB0BD1001F72D9 /* Build configuration list for PBXNativeTarget "jack_showtime Universal" */; buildPhases = ( 4B363F2C0DEB0BD1001F72D9 /* Headers */, 4B363F2D0DEB0BD1001F72D9 /* Sources */, 4B363F2F0DEB0BD1001F72D9 /* Frameworks */, 4B363F300DEB0BD1001F72D9 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_showtime Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B363F350DEB0BD1001F72D9 /* jack_showtime */; productType = "com.apple.product-type.tool"; }; 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B363F6E0DEB0D4E001F72D9 /* Build configuration list for PBXNativeTarget "jack_impulse_grabber Universal" */; buildPhases = ( 4B363F690DEB0D4E001F72D9 /* Headers */, 4B363F6A0DEB0D4E001F72D9 /* Sources */, 4B363F6C0DEB0D4E001F72D9 /* Frameworks */, 4B363F6D0DEB0D4E001F72D9 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_impulse_grabber Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */; productType = "com.apple.product-type.tool"; }; 4B3811551326878E00C61B14 /* jack_latent_client Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B38115B1326878E00C61B14 /* Build configuration list for PBXNativeTarget "jack_latent_client Universal" */; buildPhases = ( 4B3811561326878E00C61B14 /* Headers */, 4B3811571326878E00C61B14 /* Sources */, 4B3811591326878E00C61B14 /* Frameworks */, 4B38115A1326878E00C61B14 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_latent_client Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B38115F1326878E00C61B14 /* jack_latent_client */; productType = "com.apple.product-type.tool"; }; 4B38118D1326884E00C61B14 /* jack_latent_client 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B3811931326884E00C61B14 /* Build configuration list for PBXNativeTarget "jack_latent_client 64 bits" */; buildPhases = ( 4B38118E1326884E00C61B14 /* Headers */, 4B38118F1326884E00C61B14 /* Sources */, 4B3811911326884E00C61B14 /* Frameworks */, 4B3811921326884E00C61B14 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_latent_client 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B3811971326884E00C61B14 /* jack_latent_client */; productType = "com.apple.product-type.tool"; }; 4B43A8B010145F6F00E52943 /* jack_loopback Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B43A8B610145F6F00E52943 /* Build configuration list for PBXNativeTarget "jack_loopback Universal" */; buildPhases = ( 4B43A8B110145F6F00E52943 /* Headers */, 4B43A8B310145F6F00E52943 /* Sources */, 4B43A8B510145F6F00E52943 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_loopback Universal"; productName = jack_coreaudio; productReference = 4B43A8BA10145F6F00E52943 /* jack_loopback.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B43A8E31014615800E52943 /* Build configuration list for PBXNativeTarget "jack_loopback 64 bits" */; buildPhases = ( 4B43A8DE1014615800E52943 /* Headers */, 4B43A8E01014615800E52943 /* Sources */, 4B43A8E21014615800E52943 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_loopback 64 bits"; productName = jack_coreaudio; productReference = 4B43A8E71014615800E52943 /* jack_loopback.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B47AC8010B5890100469C67 /* Jackmp.framework 64 bits debugging */ = { isa = PBXNativeTarget; buildConfigurationList = 4B47ACD310B5890100469C67 /* Build configuration list for PBXNativeTarget "Jackmp.framework 64 bits debugging" */; buildPhases = ( 4B47AC8110B5890100469C67 /* Headers */, 4B47ACAC10B5890100469C67 /* Resources */, 4B47ACAD10B5890100469C67 /* Sources */, 4B47ACD010B5890100469C67 /* Rez */, 4B47ACD110B5890100469C67 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Jackmp.framework 64 bits debugging"; productName = Jack; productReference = 4B47ACD710B5890100469C67 /* Jackmp.framework */; productType = "com.apple.product-type.framework"; }; 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B5A1BB70CD1CB9E0005BF74 /* Build configuration list for PBXNativeTarget "jack_midiseq Universal" */; buildPhases = ( 4B5A1BB20CD1CB9E0005BF74 /* Headers */, 4B5A1BB30CD1CB9E0005BF74 /* Sources */, 4B5A1BB50CD1CB9E0005BF74 /* Frameworks */, 4B5A1BB60CD1CB9E0005BF74 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_midiseq Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B5A1BBB0CD1CB9E0005BF74 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4B5A1BD00CD1CCE10005BF74 /* jack_midisine Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B5A1BD60CD1CCE10005BF74 /* Build configuration list for PBXNativeTarget "jack_midisine Universal" */; buildPhases = ( 4B5A1BD10CD1CCE10005BF74 /* Headers */, 4B5A1BD20CD1CCE10005BF74 /* Sources */, 4B5A1BD40CD1CCE10005BF74 /* Frameworks */, 4B5A1BD50CD1CCE10005BF74 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_midisine Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */; productType = "com.apple.product-type.tool"; }; 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B5E08D10E5B66EE00BEE4E0 /* Build configuration list for PBXNativeTarget "netadapter Universal" */; buildPhases = ( 4B5E08C00E5B66EE00BEE4E0 /* Headers */, 4B5E08C90E5B66EE00BEE4E0 /* Sources */, 4B5E08D00E5B66EE00BEE4E0 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "netadapter Universal"; productName = jack_coreaudio; productReference = 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B6654ED127C34AE00753A79 /* jack_server_control 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B6654F3127C34AE00753A79 /* Build configuration list for PBXNativeTarget "jack_server_control 64 bits" */; buildPhases = ( 4B6654EE127C34AE00753A79 /* Headers */, 4B6654EF127C34AE00753A79 /* Sources */, 4B6654F1127C34AE00753A79 /* Frameworks */, 4B6654F2127C34AE00753A79 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_server_control 64 bits"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B6654F7127C34AE00753A79 /* jack_server_control */; productType = "com.apple.product-type.tool"; }; 4B699BA7097D421600A18468 /* jackdmp framework Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699BAD097D421600A18468 /* Build configuration list for PBXNativeTarget "jackdmp framework Universal" */; buildPhases = ( 4B699BA8097D421600A18468 /* Headers */, 4B699BA9097D421600A18468 /* Sources */, 4B699BAB097D421600A18468 /* Frameworks */, 4B699BAC097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jackdmp framework Universal"; productInstallPath = /usr/local/bin; productName = TestMacEngine; productReference = 4B699BB1097D421600A18468 /* jackdmp */; productType = "com.apple.product-type.tool"; }; 4B699C00097D421600A18468 /* Jackmp.framework Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699C43097D421600A18468 /* Build configuration list for PBXNativeTarget "Jackmp.framework Universal" */; buildPhases = ( 4B699C01097D421600A18468 /* Headers */, 4B699C23097D421600A18468 /* Resources */, 4B699C24097D421600A18468 /* Sources */, 4B699C41097D421600A18468 /* Rez */, 4B699C42097D421600A18468 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Jackmp.framework Universal"; productName = Jack; productReference = 4B699C47097D421600A18468 /* Jackmp.framework */; productType = "com.apple.product-type.framework"; }; 4B699C4C097D421600A18468 /* Jackservermp.framework Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699CA8097D421600A18468 /* Build configuration list for PBXNativeTarget "Jackservermp.framework Universal" */; buildPhases = ( 4B699C4D097D421600A18468 /* Headers */, 4B699C7C097D421600A18468 /* Resources */, 4B699C7D097D421600A18468 /* Sources */, 4B699CA6097D421600A18468 /* Rez */, 4B699CA7097D421600A18468 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Jackservermp.framework Universal"; productName = Jack; productReference = 4B699CAC097D421600A18468 /* Jackservermp.framework */; productType = "com.apple.product-type.framework"; }; 4B699CB1097D421600A18468 /* jack_metro Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699CB7097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_metro Universal" */; buildPhases = ( 4B699CB2097D421600A18468 /* Headers */, 4B699CB3097D421600A18468 /* Sources */, 4B699CB5097D421600A18468 /* Frameworks */, 4B699CB6097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_metro Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B699CBB097D421600A18468 /* jack_metro */; productType = "com.apple.product-type.tool"; }; 4B699CC1097D421600A18468 /* jack_lsp Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699CC7097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_lsp Universal" */; buildPhases = ( 4B699CC2097D421600A18468 /* Headers */, 4B699CC3097D421600A18468 /* Sources */, 4B699CC5097D421600A18468 /* Frameworks */, 4B699CC6097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_lsp Universal"; productInstallPath = /usr/local/bin; productName = jack_lsp; productReference = 4B699CCB097D421600A18468 /* jack_lsp */; productType = "com.apple.product-type.tool"; }; 4B699CD1097D421600A18468 /* jack_connect Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699CD7097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_connect Universal" */; buildPhases = ( 4B699CD2097D421600A18468 /* Headers */, 4B699CD3097D421600A18468 /* Sources */, 4B699CD5097D421600A18468 /* Frameworks */, 4B699CD6097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_connect Universal"; productInstallPath = /usr/local/bin; productName = jack_connect; productReference = 4B699CDB097D421600A18468 /* jack_connect */; productType = "com.apple.product-type.tool"; }; 4B699CE1097D421600A18468 /* jack_disconnect Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699CE7097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_disconnect Universal" */; buildPhases = ( 4B699CE2097D421600A18468 /* Headers */, 4B699CE3097D421600A18468 /* Sources */, 4B699CE5097D421600A18468 /* Frameworks */, 4B699CE6097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_disconnect Universal"; productInstallPath = /usr/local/bin; productName = jack_disconnect; productReference = 4B699CEB097D421600A18468 /* jack_disconnect */; productType = "com.apple.product-type.tool"; }; 4B699CF1097D421600A18468 /* jack_freewheel Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699CF9097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_freewheel Universal" */; buildPhases = ( 4B699CF4097D421600A18468 /* Headers */, 4B699CF5097D421600A18468 /* Sources */, 4B699CF7097D421600A18468 /* Frameworks */, 4B699CF8097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( 4B699DC0097D421700A18468 /* PBXTargetDependency */, ); name = "jack_freewheel Universal"; productInstallPath = /usr/local/bin; productName = jack_freewheel; productReference = 4B699CFD097D421600A18468 /* jack_freewheel */; productType = "com.apple.product-type.tool"; }; 4B699D03097D421600A18468 /* jack_external_metro Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699D09097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_external_metro Universal" */; buildPhases = ( 4B699D04097D421600A18468 /* Headers */, 4B699D05097D421600A18468 /* Sources */, 4B699D07097D421600A18468 /* Frameworks */, 4B699D08097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_external_metro Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B699D0D097D421600A18468 /* jack_external_metro */; productType = "com.apple.product-type.tool"; }; 4B699D13097D421600A18468 /* testAtomic Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699D1D097D421600A18468 /* Build configuration list for PBXNativeTarget "testAtomic Universal" */; buildPhases = ( 4B699D14097D421600A18468 /* Headers */, 4B699D17097D421600A18468 /* Sources */, 4B699D1B097D421600A18468 /* Frameworks */, 4B699D1C097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "testAtomic Universal"; productInstallPath = /usr/local/bin; productName = testAtomic; productReference = 4B699D21097D421600A18468 /* testAtomic */; productType = "com.apple.product-type.tool"; }; 4B699D27097D421600A18468 /* testSem Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699D35097D421600A18468 /* Build configuration list for PBXNativeTarget "testSem Universal" */; buildPhases = ( 4B699D28097D421600A18468 /* Headers */, 4B699D2B097D421600A18468 /* Sources */, 4B699D33097D421600A18468 /* Frameworks */, 4B699D34097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "testSem Universal"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4B699D39097D421600A18468 /* testSem */; productType = "com.apple.product-type.tool"; }; 4B699D3F097D421600A18468 /* zombie Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699D45097D421600A18468 /* Build configuration list for PBXNativeTarget "zombie Universal" */; buildPhases = ( 4B699D40097D421600A18468 /* Headers */, 4B699D41097D421600A18468 /* Sources */, 4B699D43097D421600A18468 /* Frameworks */, 4B699D44097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "zombie Universal"; productInstallPath = /usr/local/bin; productName = zombie; productReference = 4B699D49097D421600A18468 /* zombie */; productType = "com.apple.product-type.tool"; }; 4B699D4F097D421600A18468 /* synchroServer Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699D5D097D421600A18468 /* Build configuration list for PBXNativeTarget "synchroServer Universal" */; buildPhases = ( 4B699D50097D421600A18468 /* Headers */, 4B699D53097D421600A18468 /* Sources */, 4B699D5B097D421600A18468 /* Frameworks */, 4B699D5C097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "synchroServer Universal"; productInstallPath = /usr/local/bin; productName = synchroServer; productReference = 4B699D61097D421600A18468 /* synchroServer */; productType = "com.apple.product-type.tool"; }; 4B699D67097D421600A18468 /* synchroClient Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699D75097D421600A18468 /* Build configuration list for PBXNativeTarget "synchroClient Universal" */; buildPhases = ( 4B699D68097D421600A18468 /* Headers */, 4B699D6B097D421600A18468 /* Sources */, 4B699D73097D421600A18468 /* Frameworks */, 4B699D74097D421600A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "synchroClient Universal"; productInstallPath = /usr/local/bin; productName = synchroServer; productReference = 4B699D79097D421600A18468 /* synchroClient */; productType = "com.apple.product-type.tool"; }; 4B699D7F097D421700A18468 /* synchroServerClient Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699D8D097D421700A18468 /* Build configuration list for PBXNativeTarget "synchroServerClient Universal" */; buildPhases = ( 4B699D80097D421700A18468 /* Headers */, 4B699D83097D421700A18468 /* Sources */, 4B699D8B097D421700A18468 /* Frameworks */, 4B699D8C097D421700A18468 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "synchroServerClient Universal"; productInstallPath = /usr/local/bin; productName = synchroServer; productReference = 4B699D91097D421700A18468 /* synchroServerClient */; productType = "com.apple.product-type.tool"; }; 4B699D97097D421700A18468 /* jack_coreaudio Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699D9D097D421700A18468 /* Build configuration list for PBXNativeTarget "jack_coreaudio Universal" */; buildPhases = ( 4B699D98097D421700A18468 /* Headers */, 4B699D9A097D421700A18468 /* Sources */, 4B699D9C097D421700A18468 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_coreaudio Universal"; productName = jack_coreaudio; productReference = 4B699DA1097D421700A18468 /* jack_coreaudio.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B699DA6097D421700A18468 /* jack_dummy Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699DAC097D421700A18468 /* Build configuration list for PBXNativeTarget "jack_dummy Universal" */; buildPhases = ( 4B699DA7097D421700A18468 /* Headers */, 4B699DA9097D421700A18468 /* Sources */, 4B699DAB097D421700A18468 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_dummy Universal"; productName = jack_coreaudio; productReference = 4B699DB0097D421700A18468 /* jack_dummy.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B8692821371DB4700D2D11B /* Jacknet.framework 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B8692D71371DB4700D2D11B /* Build configuration list for PBXNativeTarget "Jacknet.framework 64 bits" */; buildPhases = ( 4B8692831371DB4700D2D11B /* Headers */, 4B8692B21371DB4700D2D11B /* Resources */, 4B8692B31371DB4700D2D11B /* Sources */, 4B8692D41371DB4700D2D11B /* Rez */, 4B8692D51371DB4700D2D11B /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Jacknet.framework 64 bits"; productName = Jack; productReference = 4B8692DB1371DB4700D2D11B /* Jacknet.framework */; productType = "com.apple.product-type.framework"; }; 4B8F16DB13290DC80002AD73 /* jack_midi_dump Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B8F16E113290DC80002AD73 /* Build configuration list for PBXNativeTarget "jack_midi_dump Universal" */; buildPhases = ( 4B8F16DC13290DC80002AD73 /* Headers */, 4B8F16DD13290DC80002AD73 /* Sources */, 4B8F16DF13290DC80002AD73 /* Frameworks */, 4B8F16E013290DC80002AD73 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_midi_dump Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B8F16E513290DC80002AD73 /* jack_midi_dump */; productType = "com.apple.product-type.tool"; }; 4B8F16E813290E0E0002AD73 /* jack_midi_dump 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B8F16EE13290E0E0002AD73 /* Build configuration list for PBXNativeTarget "jack_midi_dump 64 bits" */; buildPhases = ( 4B8F16E913290E0E0002AD73 /* Headers */, 4B8F16EA13290E0E0002AD73 /* Sources */, 4B8F16EC13290E0E0002AD73 /* Frameworks */, 4B8F16ED13290E0E0002AD73 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_midi_dump 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4B8F16F213290E0E0002AD73 /* jack_midi_dump */; productType = "com.apple.product-type.tool"; }; 4B978DB10A31CF4A009E2DD1 /* jack_portaudio Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B978DB70A31CF4A009E2DD1 /* Build configuration list for PBXNativeTarget "jack_portaudio Universal" */; buildPhases = ( 4B978DB20A31CF4A009E2DD1 /* Headers */, 4B978DB40A31CF4A009E2DD1 /* Sources */, 4B978DB60A31CF4A009E2DD1 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_portaudio Universal"; productName = jack_coreaudio; productReference = 4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */ = { isa = PBXNativeTarget; buildConfigurationList = 4BA339A810B2E36800190E3B /* Build configuration list for PBXNativeTarget "Jackservermp.framework 64 bits profiling" */; buildPhases = ( 4BA3393410B2E36800190E3B /* Headers */, 4BA3397010B2E36800190E3B /* Resources */, 4BA3397110B2E36800190E3B /* Sources */, 4BA339A510B2E36800190E3B /* Rez */, 4BA339A610B2E36800190E3B /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Jackservermp.framework 64 bits profiling"; productName = Jack; productReference = 4BA339AC10B2E36800190E3B /* Jackservermp.framework */; productType = "com.apple.product-type.framework"; }; 4BA692A60CBE4BC700EAD520 /* jack_load Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BA692AC0CBE4BC700EAD520 /* Build configuration list for PBXNativeTarget "jack_load Universal" */; buildPhases = ( 4BA692A70CBE4BC700EAD520 /* Headers */, 4BA692A80CBE4BC700EAD520 /* Sources */, 4BA692AA0CBE4BC700EAD520 /* Frameworks */, 4BA692AB0CBE4BC700EAD520 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_load Universal"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4BA692B00CBE4BC700EAD520 /* jack_load */; productType = "com.apple.product-type.tool"; }; 4BA692CA0CBE4C9000EAD520 /* jack_unload Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BA692D00CBE4C9000EAD520 /* Build configuration list for PBXNativeTarget "jack_unload Universal" */; buildPhases = ( 4BA692CB0CBE4C9000EAD520 /* Headers */, 4BA692CC0CBE4C9000EAD520 /* Sources */, 4BA692CE0CBE4C9000EAD520 /* Frameworks */, 4BA692CF0CBE4C9000EAD520 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_unload Universal"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4BA692D40CBE4C9000EAD520 /* jack_unload */; productType = "com.apple.product-type.tool"; }; 4BA7FEB90D8E76270017FF73 /* jack_server_control Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BA7FEBF0D8E76270017FF73 /* Build configuration list for PBXNativeTarget "jack_server_control Universal" */; buildPhases = ( 4BA7FEBA0D8E76270017FF73 /* Headers */, 4BA7FEBB0D8E76270017FF73 /* Sources */, 4BA7FEBD0D8E76270017FF73 /* Frameworks */, 4BA7FEBE0D8E76270017FF73 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_server_control Universal"; productInstallPath = /usr/local/bin; productName = jack_lsp; productReference = 4BA7FEC30D8E76270017FF73 /* jack_server_control */; productType = "com.apple.product-type.tool"; }; 4BD623ED0CBCF0F000DE782F /* inprocess Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BD623F30CBCF0F000DE782F /* Build configuration list for PBXNativeTarget "inprocess Universal" */; buildPhases = ( 4BD623EE0CBCF0F000DE782F /* Headers */, 4BD623F00CBCF0F000DE782F /* Sources */, 4BD623F20CBCF0F000DE782F /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "inprocess Universal"; productName = jack_coreaudio; productReference = 4BD623F70CBCF0F000DE782F /* inprocess.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BDCDB931001FB9C00B15929 /* jack_coremidi 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BDCDB991001FB9C00B15929 /* Build configuration list for PBXNativeTarget "jack_coremidi 64 bits" */; buildPhases = ( 4BDCDB941001FB9C00B15929 /* Headers */, 4BDCDB961001FB9C00B15929 /* Sources */, 4BDCDB981001FB9C00B15929 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_coremidi 64 bits"; productName = jack_coreaudio; productReference = 4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BDCDBB71001FCC000B15929 /* jack_net 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BDCDBC11001FCC000B15929 /* Build configuration list for PBXNativeTarget "jack_net 64 bits" */; buildPhases = ( 4BDCDBB81001FCC000B15929 /* Headers */, 4BDCDBBC1001FCC000B15929 /* Sources */, 4BDCDBC01001FCC000B15929 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_net 64 bits"; productName = jack_coreaudio; productReference = 4BDCDBC51001FCC000B15929 /* jack_net.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BDCDBD71001FD2D00B15929 /* netmanager 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BDCDBE41001FD2D00B15929 /* Build configuration list for PBXNativeTarget "netmanager 64 bits" */; buildPhases = ( 4BDCDBD81001FD2D00B15929 /* Headers */, 4BDCDBDD1001FD2D00B15929 /* Sources */, 4BDCDBE31001FD2D00B15929 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "netmanager 64 bits"; productName = jack_coreaudio; productReference = 4BDCDBE81001FD2D00B15929 /* netmanager.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BDCDBEC1001FD7300B15929 /* audioadapter 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BDCDBFB1001FD7300B15929 /* Build configuration list for PBXNativeTarget "audioadapter 64 bits" */; buildPhases = ( 4BDCDBED1001FD7300B15929 /* Headers */, 4BDCDBF31001FD7300B15929 /* Sources */, 4BDCDBFA1001FD7300B15929 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "audioadapter 64 bits"; productName = jack_coreaudio; productReference = 4BDCDBFF1001FD7300B15929 /* audioadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BDCDC211001FDE300B15929 /* Build configuration list for PBXNativeTarget "netadapter 64 bits" */; buildPhases = ( 4BDCDC101001FDE300B15929 /* Headers */, 4BDCDC181001FDE300B15929 /* Sources */, 4BDCDC201001FDE300B15929 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "netadapter 64 bits"; productName = jack_coreaudio; productReference = 4BDCDC251001FDE300B15929 /* netadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BE6C6910A3E096F005A203A /* jack_test Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BE6C69F0A3E096F005A203A /* Build configuration list for PBXNativeTarget "jack_test Universal" */; buildPhases = ( 4BE6C6920A3E096F005A203A /* Headers */, 4BE6C6950A3E096F005A203A /* Sources */, 4BE6C69D0A3E096F005A203A /* Frameworks */, 4BE6C69E0A3E096F005A203A /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_test Universal"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4BE6C6A30A3E096F005A203A /* jack_test */; productType = "com.apple.product-type.tool"; }; 4BE99D260AD7A04800C59091 /* jack_cpu Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BE99D2C0AD7A04800C59091 /* Build configuration list for PBXNativeTarget "jack_cpu Universal" */; buildPhases = ( 4BE99D270AD7A04800C59091 /* Headers */, 4BE99D280AD7A04800C59091 /* Sources */, 4BE99D2A0AD7A04800C59091 /* Frameworks */, 4BE99D2B0AD7A04800C59091 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_cpu Universal"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4BE99D300AD7A04800C59091 /* jack_cpu */; productType = "com.apple.product-type.tool"; }; 4BF339020F8B864B0080FB5B /* jack_coremidi Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BF339080F8B864B0080FB5B /* Build configuration list for PBXNativeTarget "jack_coremidi Universal" */; buildPhases = ( 4BF339030F8B864B0080FB5B /* Headers */, 4BF339050F8B864B0080FB5B /* Sources */, 4BF339070F8B864B0080FB5B /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "jack_coremidi Universal"; productName = jack_coreaudio; productReference = 4BF3390C0F8B864B0080FB5B /* jack_coremidi.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BFA5E8B0DEC4D9C00FA4CDB /* testMutex Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA5E940DEC4D9C00FA4CDB /* Build configuration list for PBXNativeTarget "testMutex Universal" */; buildPhases = ( 4BFA5E8C0DEC4D9C00FA4CDB /* Headers */, 4BFA5E8D0DEC4D9C00FA4CDB /* Sources */, 4BFA5E910DEC4D9C00FA4CDB /* Frameworks */, 4BFA5E930DEC4D9C00FA4CDB /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "testMutex Universal"; productInstallPath = /usr/local/bin; productName = testSem; productReference = 4BFA5E980DEC4D9C00FA4CDB /* testMutex */; productType = "com.apple.product-type.tool"; }; 4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA82880DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_evmon 64 bits" */; buildPhases = ( 4BFA82830DF6A9E40087B4E1 /* Headers */, 4BFA82840DF6A9E40087B4E1 /* Sources */, 4BFA82860DF6A9E40087B4E1 /* Frameworks */, 4BFA82870DF6A9E40087B4E1 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_evmon 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */; productType = "com.apple.product-type.tool"; }; 4BFA82950DF6A9E40087B4E1 /* jack_bufsize 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA829B0DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_bufsize 64 bits" */; buildPhases = ( 4BFA82960DF6A9E40087B4E1 /* Headers */, 4BFA82970DF6A9E40087B4E1 /* Sources */, 4BFA82990DF6A9E40087B4E1 /* Frameworks */, 4BFA829A0DF6A9E40087B4E1 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_bufsize 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */; productType = "com.apple.product-type.tool"; }; 4BFA82A10DF6A9E40087B4E1 /* jack_rec 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA82A70DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_rec 64 bits" */; buildPhases = ( 4BFA82A20DF6A9E40087B4E1 /* Headers */, 4BFA82A30DF6A9E40087B4E1 /* Sources */, 4BFA82A50DF6A9E40087B4E1 /* Frameworks */, 4BFA82A60DF6A9E40087B4E1 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_rec 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */; productType = "com.apple.product-type.tool"; }; 4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA82B30DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_monitor_client 64 bits" */; buildPhases = ( 4BFA82AE0DF6A9E40087B4E1 /* Headers */, 4BFA82AF0DF6A9E40087B4E1 /* Sources */, 4BFA82B10DF6A9E40087B4E1 /* Frameworks */, 4BFA82B20DF6A9E40087B4E1 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_monitor_client 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */; productType = "com.apple.product-type.tool"; }; 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA82BF0DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_showtime 64 bits" */; buildPhases = ( 4BFA82BA0DF6A9E40087B4E1 /* Headers */, 4BFA82BB0DF6A9E40087B4E1 /* Sources */, 4BFA82BD0DF6A9E40087B4E1 /* Frameworks */, 4BFA82BE0DF6A9E40087B4E1 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_showtime 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */; productType = "com.apple.product-type.tool"; }; 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA82CB0DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_impulse_grabber 64 bits" */; buildPhases = ( 4BFA82C60DF6A9E40087B4E1 /* Headers */, 4BFA82C70DF6A9E40087B4E1 /* Sources */, 4BFA82C90DF6A9E40087B4E1 /* Frameworks */, 4BFA82CA0DF6A9E40087B4E1 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_impulse_grabber 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */; productType = "com.apple.product-type.tool"; }; 4BFA99980AAAF3B0009E916C /* jack_iodelay Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA999E0AAAF3B0009E916C /* Build configuration list for PBXNativeTarget "jack_iodelay Universal" */; buildPhases = ( 4BFA99990AAAF3B0009E916C /* Headers */, 4BFA999A0AAAF3B0009E916C /* Sources */, 4BFA999C0AAAF3B0009E916C /* Frameworks */, 4BFA999D0AAAF3B0009E916C /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "jack_iodelay Universal"; productInstallPath = /usr/local/bin; productName = jack_lsp; productReference = 4BFA99A20AAAF3B0009E916C /* jack_iodelay */; productType = "com.apple.product-type.tool"; }; BA222AC50DC88132001A17F4 /* jack_net Universal */ = { isa = PBXNativeTarget; buildConfigurationList = BA222ACB0DC88132001A17F4 /* Build configuration list for PBXNativeTarget "jack_net Universal" */; buildPhases = ( BA222AC60DC88132001A17F4 /* Headers */, BA222AC80DC88132001A17F4 /* Sources */, BA222ACA0DC88132001A17F4 /* Frameworks */, ); buildRules = ( ); dependencies = ( 4B3224E710A3157900838A8E /* PBXTargetDependency */, ); name = "jack_net Universal"; productName = jack_coreaudio; productReference = BA222ACF0DC88132001A17F4 /* jack_net.so */; productType = "com.apple.product-type.library.dynamic"; }; BA222AE00DC882DB001A17F4 /* netmanager Universal */ = { isa = PBXNativeTarget; buildConfigurationList = BA222AE50DC882DB001A17F4 /* Build configuration list for PBXNativeTarget "netmanager Universal" */; buildPhases = ( BA222AE10DC882DB001A17F4 /* Headers */, BA222AE20DC882DB001A17F4 /* Sources */, BA222AE40DC882DB001A17F4 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "netmanager Universal"; productName = jack_coreaudio; productReference = BA222AE90DC882DB001A17F4 /* netmanager.so */; productType = "com.apple.product-type.library.dynamic"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 4B699DD5097D427F00A18468 /* Build configuration list for PBXProject "Jackdmp" */; compatibilityVersion = "Xcode 2.4"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 08FB7794FE84155DC02AAC07 /* JackServer */; projectDirPath = ""; projectRoot = ""; targets = ( 4B699B26097D421600A18468 /* All Universal 32 bits */, 4B35C6420D47339B000DE7AE /* All Universal 32/64 bits */, 4B699BA7097D421600A18468 /* jackdmp framework Universal */, 4B699C00097D421600A18468 /* Jackmp.framework Universal */, 4B699C4C097D421600A18468 /* Jackservermp.framework Universal */, 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */, 4B5A1BD00CD1CCE10005BF74 /* jack_midisine Universal */, 4B8F16DB13290DC80002AD73 /* jack_midi_dump Universal */, 4B363DCE0DEB02F6001F72D9 /* jack_alias Universal */, 4B699CB1097D421600A18468 /* jack_metro Universal */, 4B699CC1097D421600A18468 /* jack_lsp Universal */, 4B699CD1097D421600A18468 /* jack_connect Universal */, 4B699CE1097D421600A18468 /* jack_disconnect Universal */, 4B699CF1097D421600A18468 /* jack_freewheel Universal */, 4BFA99980AAAF3B0009E916C /* jack_iodelay Universal */, 4B699D03097D421600A18468 /* jack_external_metro Universal */, 4B699D13097D421600A18468 /* testAtomic Universal */, 4B699D27097D421600A18468 /* testSem Universal */, 4BFA5E8B0DEC4D9C00FA4CDB /* testMutex Universal */, 4B699D3F097D421600A18468 /* zombie Universal */, 4BE6C6910A3E096F005A203A /* jack_test Universal */, 4BA7FEB90D8E76270017FF73 /* jack_server_control Universal */, 4BE99D260AD7A04800C59091 /* jack_cpu Universal */, 4BA692A60CBE4BC700EAD520 /* jack_load Universal */, 4BA692CA0CBE4C9000EAD520 /* jack_unload Universal */, 4B0A28DC0D52073D002EFF74 /* jack_thread_wait */, 4B363E100DEB03C5001F72D9 /* jack_evmon Universal */, 4B363E440DEB0775001F72D9 /* jack_bufsize Universal */, 4B363EDF0DEB091C001F72D9 /* jack_rec Universal */, 4B3811551326878E00C61B14 /* jack_latent_client Universal */, 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */, 4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */, 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */, 4B32255710A3187800838A8E /* jack_netsource Universal */, 4B699D4F097D421600A18468 /* synchroServer Universal */, 4B699D67097D421600A18468 /* synchroClient Universal */, 4B699D7F097D421700A18468 /* synchroServerClient Universal */, 4B699D97097D421700A18468 /* jack_coreaudio Universal */, 4B978DB10A31CF4A009E2DD1 /* jack_portaudio Universal */, 4BF339020F8B864B0080FB5B /* jack_coremidi Universal */, 4B43A8B010145F6F00E52943 /* jack_loopback Universal */, 4B699DA6097D421700A18468 /* jack_dummy Universal */, BA222AC50DC88132001A17F4 /* jack_net Universal */, 4B3224D710A3156800838A8E /* jack_netone Universal */, 4BD623ED0CBCF0F000DE782F /* inprocess Universal */, BA222AE00DC882DB001A17F4 /* netmanager Universal */, 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */, 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */, 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */, 4B35C4270D4731D1000DE7AE /* Jackmp.framework 64 bits */, 4B47AC8010B5890100469C67 /* Jackmp.framework 64 bits debugging */, 4B35C4850D4731D1000DE7AE /* Jackservermp.framework 64 bits */, 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */, 4B8692821371DB4700D2D11B /* Jacknet.framework 64 bits */, 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */, 4B35C5160D4731D1000DE7AE /* jack_midisine 64 bits */, 4B8F16E813290E0E0002AD73 /* jack_midi_dump 64 bits */, 4B2021DC133A9BA40019E213 /* jack_midi_latency 64 bits */, 4B35C5220D4731D1000DE7AE /* jack_metro 64 bits */, 4B35C52E0D4731D1000DE7AE /* jack_lsp 64 bits */, 4B35C53A0D4731D1000DE7AE /* jack_connect 64 bits */, 4B35C5460D4731D1000DE7AE /* jack_disconnect 64 bits */, 4B35C5520D4731D2000DE7AE /* jack_freewheel 64 bits */, 4B35C5600D4731D2000DE7AE /* jack_iodelay 64 bits */, 4B35C56C0D4731D2000DE7AE /* jack_external_metro 64 bits */, 4B35C5780D4731D2000DE7AE /* testAtomic 64 bits */, 4B35C5880D4731D2000DE7AE /* testSem 64 bits */, 4B35C59C0D4731D2000DE7AE /* zombie 64 bits */, 4B35C5A80D4731D2000DE7AE /* jack_test 64 bits */, 4B35C5B40D4731D2000DE7AE /* jack_cpu 64 bits */, 4B35C5C00D4731D2000DE7AE /* jack_load 64 bits */, 4B35C5CC0D4731D2000DE7AE /* jack_unload 64 bits */, 4B0A29230D52108E002EFF74 /* jack_thread_wait 64 bits */, 4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */, 4BFA82950DF6A9E40087B4E1 /* jack_bufsize 64 bits */, 4BFA82A10DF6A9E40087B4E1 /* jack_rec 64 bits */, 4B38118D1326884E00C61B14 /* jack_latent_client 64 bits */, 4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */, 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */, 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */, 4B32257110A3190C00838A8E /* jack_netsource 64 bits */, 4B6654ED127C34AE00753A79 /* jack_server_control 64 bits */, 4B35C5D80D4731D2000DE7AE /* synchroServer 64 bits */, 4B35C5EC0D4731D2000DE7AE /* synchroClient 64 bits */, 4B35C6000D4731D2000DE7AE /* synchroServerClient 64 bits */, 4B35C6140D4731D2000DE7AE /* jack_coreaudio 64 bits */, 4B35C61F0D4731D2000DE7AE /* jack_portaudio 64 bits */, 4B35C62A0D4731D2000DE7AE /* jack_dummy 64 bits */, 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */, 4BDCDB931001FB9C00B15929 /* jack_coremidi 64 bits */, 4BDCDBB71001FCC000B15929 /* jack_net 64 bits */, 4B32251D10A316B200838A8E /* jack_netone 64 bits */, 4BDCDBD71001FD2D00B15929 /* netmanager 64 bits */, 4BDCDBEC1001FD7300B15929 /* audioadapter 64 bits */, 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */, 4B35C6350D4731D3000DE7AE /* inprocess 64 bits */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 4B35C4560D4731D1000DE7AE /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C4C20D4731D1000DE7AE /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B47ACAC10B5890100469C67 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699C23097D421600A18468 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699C7C097D421600A18468 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B8692B21371DB4700D2D11B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA3397010B2E36800190E3B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 4B0A28E10D52073D002EFF74 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B0A29280D52108E002EFF74 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B2021E1133A9BA40019E213 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B32255C10A3187800838A8E /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B32257610A3190C00838A8E /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C4200D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C47D0D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C4F60D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C50F0D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C51B0D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5270D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5330D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C53F0D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C54B0D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5590D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5650D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5710D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5810D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5950D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5A10D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5AD0D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5B90D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5C50D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5D10D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5E50D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5F90D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C60D0D4731D2000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363DD30DEB02F6001F72D9 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363E150DEB03C5001F72D9 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363E490DEB0775001F72D9 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363EE40DEB091C001F72D9 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F190DEB0A6A001F72D9 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F300DEB0BD1001F72D9 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F6D0DEB0D4E001F72D9 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B38115A1326878E00C61B14 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B3811921326884E00C61B14 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B47ACD010B5890100469C67 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B5A1BB60CD1CB9E0005BF74 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B5A1BD50CD1CCE10005BF74 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B6654F2127C34AE00753A79 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699BAC097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699C41097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CA6097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CB6097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CC6097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CD6097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CE6097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CF8097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D08097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D1C097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D34097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D44097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D5C097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D74097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D8C097D421700A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B8692D41371DB4700D2D11B /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B8F16E013290DC80002AD73 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B8F16ED13290E0E0002AD73 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA339A510B2E36800190E3B /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA692AB0CBE4BC700EAD520 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA692CF0CBE4C9000EAD520 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BA7FEBE0D8E76270017FF73 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BE6C69E0A3E096F005A203A /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BE99D2B0AD7A04800C59091 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA5E930DEC4D9C00FA4CDB /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82870DF6A9E40087B4E1 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA829A0DF6A9E40087B4E1 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82A60DF6A9E40087B4E1 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82B20DF6A9E40087B4E1 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82BE0DF6A9E40087B4E1 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82CA0DF6A9E40087B4E1 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA999D0AAAF3B0009E916C /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 4B0A28DE0D52073D002EFF74 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B0A28ED0D520852002EFF74 /* tw.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B0A29250D52108E002EFF74 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B0A29260D52108E002EFF74 /* tw.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B19B2F90E23620F00DD4A82 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B19B3130E2362E800DD4A82 /* JackAudioAdapter.cpp in Sources */, 4B19B3150E2362E800DD4A82 /* JackAudioAdapterInterface.cpp in Sources */, 4B19B31B0E2362E800DD4A82 /* JackLibSampleRateResampler.cpp in Sources */, 4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */, 4BF4BAB10E3480AB00403CDF /* JackAudioAdapterFactory.cpp in Sources */, 4BE5FED10E725C320020B576 /* JackCoreAudioAdapter.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B2021DE133A9BA40019E213 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B20220A133A9C1C0019E213 /* midi_latency_test.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B3224DC10A3156800838A8E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B3224EA10A315B100838A8E /* JackNetOneDriver.cpp in Sources */, 4B3224F010A315C400838A8E /* netjack_packet.c in Sources */, 4B3224F210A315C400838A8E /* netjack.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B32252210A316B200838A8E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B32253110A3173900838A8E /* JackNetOneDriver.cpp in Sources */, 4B32253310A3173B00838A8E /* netjack.c in Sources */, 4B32253510A3173D00838A8E /* netjack_packet.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B32255910A3187800838A8E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B32256410A318E300838A8E /* netsource.c in Sources */, 4B32256D10A318FC00838A8E /* netjack_packet.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B32257310A3190C00838A8E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B32257F10A3195900838A8E /* netjack_packet.c in Sources */, 4B32258110A3195B00838A8E /* netsource.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C41D0D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C41E0D4731D1000DE7AE /* Jackdmp.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C4570D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C45B0D4731D1000DE7AE /* JackShmMem.cpp in Sources */, 4B35C45C0D4731D1000DE7AE /* shm.c in Sources */, 4B35C45E0D4731D1000DE7AE /* JackActivationCount.cpp in Sources */, 4B35C45F0D4731D1000DE7AE /* JackGraphManager.cpp in Sources */, 4B35C4600D4731D1000DE7AE /* JackPort.cpp in Sources */, 4B35C4610D4731D1000DE7AE /* JackClient.cpp in Sources */, 4B35C4620D4731D1000DE7AE /* JackAPI.cpp in Sources */, 4B35C4630D4731D1000DE7AE /* JackLibClient.cpp in Sources */, 4B35C4640D4731D1000DE7AE /* JackLibAPI.cpp in Sources */, 4B35C4650D4731D1000DE7AE /* JackConnectionManager.cpp in Sources */, 4B35C4660D4731D1000DE7AE /* JackFrameTimer.cpp in Sources */, 4B35C4680D4731D1000DE7AE /* JackMachSemaphore.cpp in Sources */, 4B35C4690D4731D1000DE7AE /* JackMachThread.cpp in Sources */, 4B35C4700D4731D1000DE7AE /* JackGlobals.cpp in Sources */, 4B35C4720D4731D1000DE7AE /* ringbuffer.c in Sources */, 4B35C4730D4731D1000DE7AE /* JackDebugClient.cpp in Sources */, 4B35C4740D4731D1000DE7AE /* JackTransportEngine.cpp in Sources */, 4B35C4760D4731D1000DE7AE /* timestamps.c in Sources */, 4B35C4770D4731D1000DE7AE /* JackPortType.cpp in Sources */, 4B35C4780D4731D1000DE7AE /* JackAudioPort.cpp in Sources */, 4B35C4790D4731D1000DE7AE /* JackMidiPort.cpp in Sources */, 4B35C47A0D4731D1000DE7AE /* JackMidiAPI.cpp in Sources */, 4B35C47B0D4731D1000DE7AE /* JackEngineControl.cpp in Sources */, 4B35C47C0D4731D1000DE7AE /* JackTools.cpp in Sources */, 4B9A26610DBF8ADD006E9FBC /* JackError.cpp in Sources */, 4B4F9C900DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */, 4B93F19C0E87998200E4ECCD /* JackPosixServerLaunch.cpp in Sources */, 4B93F19D0E87998400E4ECCD /* JackPosixThread.cpp in Sources */, 4B93F1C00E87A35400E4ECCD /* JackMachTime.c in Sources */, 4B8A38F1117B827E00664E07 /* JackSocketClientChannel.cpp in Sources */, 4B8A38F6117B82AB00664E07 /* JackSocket.cpp in Sources */, 4B327BAB14B4B50400976483 /* JackPosixMutex.cpp in Sources */, 4B1499F614BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, 4BB4215214D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */, 4B4C3B641BC2FF670004CC35 /* JackPosixSemaphore.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C4C30D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C4C50D4731D1000DE7AE /* JackShmMem.cpp in Sources */, 4B35C4C60D4731D1000DE7AE /* shm.c in Sources */, 4B35C4C80D4731D1000DE7AE /* JackActivationCount.cpp in Sources */, 4B35C4C90D4731D1000DE7AE /* JackGraphManager.cpp in Sources */, 4B35C4CA0D4731D1000DE7AE /* JackPort.cpp in Sources */, 4B35C4CB0D4731D1000DE7AE /* JackClient.cpp in Sources */, 4B35C4CC0D4731D1000DE7AE /* JackAPI.cpp in Sources */, 4B35C4CD0D4731D1000DE7AE /* JackConnectionManager.cpp in Sources */, 4B35C4CE0D4731D1000DE7AE /* JackFrameTimer.cpp in Sources */, 4B35C4D00D4731D1000DE7AE /* JackMachSemaphore.cpp in Sources */, 4B35C4D10D4731D1000DE7AE /* JackMachThread.cpp in Sources */, 4B35C4D50D4731D1000DE7AE /* JackGlobals.cpp in Sources */, 4B35C4D70D4731D1000DE7AE /* ringbuffer.c in Sources */, 4B35C4D80D4731D1000DE7AE /* JackAudioDriver.cpp in Sources */, 4B35C4D90D4731D1000DE7AE /* JackFreewheelDriver.cpp in Sources */, 4B35C4DA0D4731D1000DE7AE /* JackThreadedDriver.cpp in Sources */, 4B35C4DB0D4731D1000DE7AE /* JackDriver.cpp in Sources */, 4B35C4DC0D4731D1000DE7AE /* JackDriverLoader.cpp in Sources */, 4B35C4DD0D4731D1000DE7AE /* JackEngine.cpp in Sources */, 4B35C4DE0D4731D1000DE7AE /* JackExternalClient.cpp in Sources */, 4B35C4DF0D4731D1000DE7AE /* JackInternalClient.cpp in Sources */, 4B35C4E20D4731D1000DE7AE /* JackServer.cpp in Sources */, 4B35C4EB0D4731D1000DE7AE /* JackTransportEngine.cpp in Sources */, 4B35C4EC0D4731D1000DE7AE /* JackServerAPI.cpp in Sources */, 4B35C4ED0D4731D1000DE7AE /* JackServerGlobals.cpp in Sources */, 4B35C4EE0D4731D1000DE7AE /* timestamps.c in Sources */, 4B35C4EF0D4731D1000DE7AE /* JackPortType.cpp in Sources */, 4B35C4F00D4731D1000DE7AE /* JackAudioPort.cpp in Sources */, 4B35C4F10D4731D1000DE7AE /* JackMidiPort.cpp in Sources */, 4B35C4F20D4731D1000DE7AE /* JackMidiAPI.cpp in Sources */, 4B35C4F30D4731D1000DE7AE /* JackEngineControl.cpp in Sources */, 4B35C4F40D4731D1000DE7AE /* JackDebugClient.cpp in Sources */, 4B35C4F50D4731D1000DE7AE /* JackTools.cpp in Sources */, BA222ADA0DC88269001A17F4 /* JackNetTool.cpp in Sources */, 4B9A26640DBF8B14006E9FBC /* JackError.cpp in Sources */, 4B4F9C920DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */, 4B4CA9780E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp in Sources */, 4B4E9AFC0E5F1090000A3278 /* JackControlAPI.cpp in Sources */, 4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */, 4B93F22B0E87A72500E4ECCD /* JackMachTime.c in Sources */, 4BBAE4130F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, 4BF339210F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, 4BDCDBD11001FD0100B15929 /* JackWaitThreadedDriver.cpp in Sources */, 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */, 4BC2CA59113C6CB60076717C /* JackNetInterface.cpp in Sources */, 4BC2CA5B113C6CBE0076717C /* JackNetUnixSocket.cpp in Sources */, 4B8A38A7117B80D300664E07 /* JackSocket.cpp in Sources */, 4B8A38AE117B811100664E07 /* JackSocketNotifyChannel.cpp in Sources */, 4B8A38B1117B812D00664E07 /* JackSocketServerChannel.cpp in Sources */, 4B8A38B2117B813400664E07 /* JackSocketServerNotifyChannel.cpp in Sources */, 4B97B6601344B48F00794F57 /* JackMidiAsyncQueue.cpp in Sources */, 4B97B6621344B49C00794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */, 4B97B6641344B4AE00794F57 /* JackMidiBufferReadQueue.cpp in Sources */, 4B97B6691344B4CE00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */, 4B97B66E1344B4D500794F57 /* JackMidiReadQueue.cpp in Sources */, 4B97B6701344B4E300794F57 /* JackMidiReceiveQueue.cpp in Sources */, 4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */, 4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */, 4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */, 4B21795113E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */, 4B67AB8E14B4B03800B4AA9A /* JackException.cpp in Sources */, 4B327BA814B4B50400976483 /* JackPosixMutex.cpp in Sources */, 4B1499F014BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, 4B90669A14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, 4BB4215814D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */, 4B4C3B6C1BC2FFC40004CC35 /* JackPosixSemaphore.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C50C0D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C50D0D4731D1000DE7AE /* midiseq.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5180D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5190D4731D1000DE7AE /* midisine.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5240D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5250D4731D1000DE7AE /* metro.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5300D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5310D4731D1000DE7AE /* lsp.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C53C0D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C53D0D4731D1000DE7AE /* connect.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5480D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5490D4731D1000DE7AE /* connect.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5560D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5570D4731D2000DE7AE /* freewheel.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5620D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B3814211327AA6800C61B14 /* iodelay.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C56E0D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C57C0D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C57D0D4731D2000DE7AE /* testAtomic.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C58C0D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C58D0D4731D2000DE7AE /* testSem.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C59E0D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C59F0D4731D2000DE7AE /* zombie.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5AA0D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5AB0D4731D2000DE7AE /* test.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5B60D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5B70D4731D2000DE7AE /* cpu.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5C20D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5C30D4731D2000DE7AE /* ipload.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5CE0D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5CF0D4731D2000DE7AE /* ipunload.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5DC0D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5DD0D4731D2000DE7AE /* JackMachSemaphore.cpp in Sources */, 4B35C5E00D4731D2000DE7AE /* JackMachThread.cpp in Sources */, 4B35C5E20D4731D2000DE7AE /* testSynchroServer.cpp in Sources */, 4B9A26790DBF8B88006E9FBC /* JackError.cpp in Sources */, 4B4F9D820DC2178E00706CB0 /* JackMessageBuffer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C5F00D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C5F60D4731D2000DE7AE /* testSynchroClient.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6040D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C60A0D4731D2000DE7AE /* testSynchroServerClient.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6170D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BA4ADB40E87AB2500F26C85 /* JackCoreAudioDriver.cpp in Sources */, 4BAA150514F04FB600402512 /* JackAC3Encoder.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6220D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C62D0D4731D2000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C62E0D4731D2000DE7AE /* JackDummyDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B35C6370D4731D3000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B35C6380D4731D3000DE7AE /* inprocess.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B363DD00DEB02F6001F72D9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B363DDF0DEB034E001F72D9 /* alias.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B363E120DEB03C5001F72D9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B363E210DEB0401001F72D9 /* evmon.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B363E460DEB0775001F72D9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B363E720DEB0808001F72D9 /* bufsize.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B363EE10DEB091C001F72D9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B363EEE0DEB094B001F72D9 /* capture_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F160DEB0A6A001F72D9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B363F230DEB0AB0001F72D9 /* monitor_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F2D0DEB0BD1001F72D9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B363F3E0DEB0C31001F72D9 /* showtime.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B363F6A0DEB0D4E001F72D9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B363F760DEB0D7D001F72D9 /* impulse_grabber.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B3811571326878E00C61B14 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B3811FC13269C8300C61B14 /* latent_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B38118F1326884E00C61B14 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B3811FB13269C8300C61B14 /* latent_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B43A8B310145F6F00E52943 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B43A8CA1014605000E52943 /* JackLoopbackDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B43A8E01014615800E52943 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B43A8E11014615800E52943 /* JackLoopbackDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B47ACAD10B5890100469C67 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B47ACB110B5890100469C67 /* JackShmMem.cpp in Sources */, 4B47ACB210B5890100469C67 /* shm.c in Sources */, 4B47ACB310B5890100469C67 /* JackActivationCount.cpp in Sources */, 4B47ACB410B5890100469C67 /* JackGraphManager.cpp in Sources */, 4B47ACB510B5890100469C67 /* JackPort.cpp in Sources */, 4B47ACB610B5890100469C67 /* JackClient.cpp in Sources */, 4B47ACB710B5890100469C67 /* JackAPI.cpp in Sources */, 4B47ACB810B5890100469C67 /* JackLibClient.cpp in Sources */, 4B47ACB910B5890100469C67 /* JackLibAPI.cpp in Sources */, 4B47ACBA10B5890100469C67 /* JackConnectionManager.cpp in Sources */, 4B47ACBB10B5890100469C67 /* JackFrameTimer.cpp in Sources */, 4B47ACBC10B5890100469C67 /* JackMachSemaphore.cpp in Sources */, 4B47ACBD10B5890100469C67 /* JackMachThread.cpp in Sources */, 4B47ACBF10B5890100469C67 /* JackGlobals.cpp in Sources */, 4B47ACC010B5890100469C67 /* ringbuffer.c in Sources */, 4B47ACC110B5890100469C67 /* JackDebugClient.cpp in Sources */, 4B47ACC210B5890100469C67 /* JackTransportEngine.cpp in Sources */, 4B47ACC310B5890100469C67 /* timestamps.c in Sources */, 4B47ACC410B5890100469C67 /* JackPortType.cpp in Sources */, 4B47ACC510B5890100469C67 /* JackAudioPort.cpp in Sources */, 4B47ACC610B5890100469C67 /* JackMidiPort.cpp in Sources */, 4B47ACC710B5890100469C67 /* JackMidiAPI.cpp in Sources */, 4B47ACC810B5890100469C67 /* JackEngineControl.cpp in Sources */, 4B47ACC910B5890100469C67 /* JackTools.cpp in Sources */, 4B47ACCA10B5890100469C67 /* JackError.cpp in Sources */, 4B47ACCB10B5890100469C67 /* JackMessageBuffer.cpp in Sources */, 4B47ACCC10B5890100469C67 /* JackPosixServerLaunch.cpp in Sources */, 4B47ACCD10B5890100469C67 /* JackPosixThread.cpp in Sources */, 4B47ACCE10B5890100469C67 /* JackMachTime.c in Sources */, 4B327BAC14B4B50400976483 /* JackPosixMutex.cpp in Sources */, 4B1499F814BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, 4BB4215514D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */, 4B4C3B6A1BC2FFB30004CC35 /* JackPosixSemaphore.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B5A1BB30CD1CB9E0005BF74 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B5A1BBE0CD1CC110005BF74 /* midiseq.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B5A1BD20CD1CCE10005BF74 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B5A1BDD0CD1CD420005BF74 /* midisine.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B5E08C90E5B66EE00BEE4E0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B5E08CC0E5B66EE00BEE4E0 /* JackAudioAdapterInterface.cpp in Sources */, 4B5E08CD0E5B66EE00BEE4E0 /* JackLibSampleRateResampler.cpp in Sources */, 4B5E08CE0E5B66EE00BEE4E0 /* JackResampler.cpp in Sources */, 4B5E08E10E5B676C00BEE4E0 /* JackNetAdapter.cpp in Sources */, 4B5E08EE0E5B680200BEE4E0 /* JackAudioAdapter.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B6654EF127C34AE00753A79 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B6654FC127C350100753A79 /* server_control.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699BA9097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699BAA097D421600A18468 /* Jackdmp.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699C24097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699C28097D421600A18468 /* JackShmMem.cpp in Sources */, 4B699C29097D421600A18468 /* shm.c in Sources */, 4B699C2B097D421600A18468 /* JackActivationCount.cpp in Sources */, 4B699C2C097D421600A18468 /* JackGraphManager.cpp in Sources */, 4B699C2D097D421600A18468 /* JackPort.cpp in Sources */, 4B699C2E097D421600A18468 /* JackClient.cpp in Sources */, 4B699C2F097D421600A18468 /* JackAPI.cpp in Sources */, 4B699C30097D421600A18468 /* JackLibClient.cpp in Sources */, 4B699C31097D421600A18468 /* JackLibAPI.cpp in Sources */, 4B699C32097D421600A18468 /* JackConnectionManager.cpp in Sources */, 4B699C33097D421600A18468 /* JackFrameTimer.cpp in Sources */, 4B699C35097D421600A18468 /* JackMachSemaphore.cpp in Sources */, 4B699C36097D421600A18468 /* JackMachThread.cpp in Sources */, 4B699C3D097D421600A18468 /* JackGlobals.cpp in Sources */, 4B699C3F097D421600A18468 /* ringbuffer.c in Sources */, 4B699C40097D421600A18468 /* JackDebugClient.cpp in Sources */, 4BF520530CB8D0E80037470E /* timestamps.c in Sources */, 4BAB95B80B9E20B800A0C723 /* JackPortType.cpp in Sources */, 4BAB95ED0B9E21A500A0C723 /* JackAudioPort.cpp in Sources */, 4B80D7E90BA0D17400F035BB /* JackMidiPort.cpp in Sources */, 4B80D7EA0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */, 4BE4CC010CDA153400CCF5BB /* JackTools.cpp in Sources */, 4B9A25B50DBF8330006E9FBC /* JackError.cpp in Sources */, 4B4F9C8E0DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */, 4BB9D4B40E2610B400351653 /* JackTransportEngine.cpp in Sources */, 4BB9D4E40E26112900351653 /* JackEngineControl.cpp in Sources */, 4BC3B6A40E703B2E0066E42F /* JackPosixThread.cpp in Sources */, 4BF5FBBC0E878B9C003D2374 /* JackPosixServerLaunch.cpp in Sources */, 4BF5FBCB0E878D24003D2374 /* JackMachTime.c in Sources */, 4B2209EC12F6BC2100E5DC26 /* JackSocket.cpp in Sources */, 4B2209EE12F6BC2300E5DC26 /* JackSocketClientChannel.cpp in Sources */, 4B327BAA14B4B50400976483 /* JackPosixMutex.cpp in Sources */, 4B1499F414BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, 4BB4214C14D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699C7D097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699C7F097D421600A18468 /* JackShmMem.cpp in Sources */, 4B699C80097D421600A18468 /* shm.c in Sources */, 4B699C82097D421600A18468 /* JackActivationCount.cpp in Sources */, 4B699C83097D421600A18468 /* JackGraphManager.cpp in Sources */, 4B699C84097D421600A18468 /* JackPort.cpp in Sources */, 4B699C85097D421600A18468 /* JackClient.cpp in Sources */, 4B699C86097D421600A18468 /* JackAPI.cpp in Sources */, 4B699C87097D421600A18468 /* JackConnectionManager.cpp in Sources */, 4B699C88097D421600A18468 /* JackFrameTimer.cpp in Sources */, 4B699C8A097D421600A18468 /* JackMachSemaphore.cpp in Sources */, 4B699C8B097D421600A18468 /* JackMachThread.cpp in Sources */, 4B699C8F097D421600A18468 /* JackGlobals.cpp in Sources */, 4B699C91097D421600A18468 /* ringbuffer.c in Sources */, 4B699C92097D421600A18468 /* JackAudioDriver.cpp in Sources */, 4B699C93097D421600A18468 /* JackFreewheelDriver.cpp in Sources */, 4B699C94097D421600A18468 /* JackThreadedDriver.cpp in Sources */, 4B699C95097D421600A18468 /* JackDriver.cpp in Sources */, 4B699C96097D421600A18468 /* JackDriverLoader.cpp in Sources */, 4B699C97097D421600A18468 /* JackEngine.cpp in Sources */, 4B699C99097D421600A18468 /* JackExternalClient.cpp in Sources */, 4B699C9A097D421600A18468 /* JackInternalClient.cpp in Sources */, 4B699C9D097D421600A18468 /* JackServer.cpp in Sources */, 4BD4B4D909BACD9600750C0F /* JackTransportEngine.cpp in Sources */, 4BC216850A444BAD00BDA09F /* JackServerAPI.cpp in Sources */, 4BC216890A444BDE00BDA09F /* JackServerGlobals.cpp in Sources */, 4BF520540CB8D0E80037470E /* timestamps.c in Sources */, 4BAB95BA0B9E20B800A0C723 /* JackPortType.cpp in Sources */, 4BAB95EE0B9E21A500A0C723 /* JackAudioPort.cpp in Sources */, 4B80D7EC0BA0D17400F035BB /* JackMidiPort.cpp in Sources */, 4B80D7ED0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */, 4B6F7AEE0CD0CDBD00F48A9D /* JackEngineControl.cpp in Sources */, 4B5DB9830CD2429A00EBA5EE /* JackDebugClient.cpp in Sources */, 4BE4CC030CDA153500CCF5BB /* JackTools.cpp in Sources */, BA222AD80DC88268001A17F4 /* JackNetTool.cpp in Sources */, 4B9A25B60DBF8330006E9FBC /* JackError.cpp in Sources */, 4B4F9C8C0DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */, 4BBC93BA0DF9736C002DF220 /* JackWaitThreadedDriver.cpp in Sources */, 4B4CA9760E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp in Sources */, 4B4E9AFA0E5F1090000A3278 /* JackControlAPI.cpp in Sources */, 4BC3B6A60E703B2E0066E42F /* JackPosixThread.cpp in Sources */, 4BF5FBCA0E878D24003D2374 /* JackMachTime.c in Sources */, 4BF2841A0F31B4BC00B05BE3 /* JackArgParser.cpp in Sources */, 4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, 4BF339230F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, 4BC2CA55113C6C930076717C /* JackNetInterface.cpp in Sources */, 4BC2CA57113C6C9B0076717C /* JackNetUnixSocket.cpp in Sources */, 4B2209E112F6BBF300E5DC26 /* JackSocketServerChannel.cpp in Sources */, 4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */, 4B2209E612F6BC0200E5DC26 /* JackSocket.cpp in Sources */, 4B2209E912F6BC1500E5DC26 /* JackSocketNotifyChannel.cpp in Sources */, 4B97B6381344B3C100794F57 /* JackMidiAsyncQueue.cpp in Sources */, 4B97B63A1344B3C700794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */, 4B97B63E1344B3F100794F57 /* JackMidiBufferReadQueue.cpp in Sources */, 4B97B6531344B41E00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */, 4B97B6571344B43A00794F57 /* JackMidiReadQueue.cpp in Sources */, 4B97B6581344B43F00794F57 /* JackMidiReceiveQueue.cpp in Sources */, 4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */, 4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */, 4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */, 4B21794F13E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */, 4B67AB8D14B4B03800B4AA9A /* JackException.cpp in Sources */, 4B327BA714B4B50400976483 /* JackPosixMutex.cpp in Sources */, 4B1499FA14BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, 4B90669E14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, 4BB4214F14D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CB3097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699CB4097D421600A18468 /* metro.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CC3097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699CC4097D421600A18468 /* lsp.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CD3097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B60CE490AAABA31004956AA /* connect.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CE3097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B60CE4A0AAABA31004956AA /* connect.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699CF5097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699CF6097D421600A18468 /* freewheel.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D05097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D17097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699D18097D421600A18468 /* testAtomic.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D2B097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699D2C097D421600A18468 /* testSem.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D41097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699D42097D421600A18468 /* zombie.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D53097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699D59097D421600A18468 /* testSynchroServer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D6B097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699D71097D421600A18468 /* testSynchroClient.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D83097D421700A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699D89097D421700A18468 /* testSynchroServerClient.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699D9A097D421700A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BE5FECD0E725C090020B576 /* JackCoreAudioDriver.cpp in Sources */, 4BAA150314F04FB600402512 /* JackAC3Encoder.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B699DA9097D421700A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B699DAA097D421700A18468 /* JackDummyDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B8692B31371DB4700D2D11B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B8692F81371DC5200D2D11B /* JackAudioAdapterInterface.cpp in Sources */, 4B8692FB1371DC7100D2D11B /* JackGlobals.cpp in Sources */, 4B8692FE1371DC9700D2D11B /* JackMachThread.cpp in Sources */, 4B8693141371DCCA00D2D11B /* JackMachTime.c in Sources */, 4B8693161371DD0A00D2D11B /* JackNetAPI.cpp in Sources */, 4B8693171371DD2400D2D11B /* JackNetInterface.cpp in Sources */, 4B8693191371DD3B00D2D11B /* JackNetTool.cpp in Sources */, 4B86931B1371DD4C00D2D11B /* JackNetUnixSocket.cpp in Sources */, 4B8693231371DD6000D2D11B /* JackPosixThread.cpp in Sources */, 4B8693251371DD7E00D2D11B /* JackResampler.cpp in Sources */, 4B86932C1371DD9B00D2D11B /* ringbuffer.c in Sources */, 4B86934D1371DEBA00D2D11B /* JackLibSampleRateResampler.cpp in Sources */, 4B327BD614B4B6E700976483 /* JackException.cpp in Sources */, 4BF1007C15135D8200B88F80 /* JackPosixMutex.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B8F16DD13290DC80002AD73 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B8F16F51329161E0002AD73 /* midi_dump.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B8F16EA13290E0E0002AD73 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B8F16F61329161E0002AD73 /* midi_dump.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B978DB40A31CF4A009E2DD1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BBB00D30E72614F0018AB1B /* JackPortAudioDevices.cpp in Sources */, 4BBB00D50E72614F0018AB1B /* JackPortAudioDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BA3397110B2E36800190E3B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BA3397310B2E36800190E3B /* JackShmMem.cpp in Sources */, 4BA3397410B2E36800190E3B /* shm.c in Sources */, 4BA3397510B2E36800190E3B /* JackActivationCount.cpp in Sources */, 4BA3397610B2E36800190E3B /* JackGraphManager.cpp in Sources */, 4BA3397710B2E36800190E3B /* JackPort.cpp in Sources */, 4BA3397810B2E36800190E3B /* JackClient.cpp in Sources */, 4BA3397910B2E36800190E3B /* JackAPI.cpp in Sources */, 4BA3397A10B2E36800190E3B /* JackConnectionManager.cpp in Sources */, 4BA3397B10B2E36800190E3B /* JackFrameTimer.cpp in Sources */, 4BA3397C10B2E36800190E3B /* JackMachSemaphore.cpp in Sources */, 4BA3397D10B2E36800190E3B /* JackMachThread.cpp in Sources */, 4BA3397E10B2E36800190E3B /* JackGlobals.cpp in Sources */, 4BA3397F10B2E36800190E3B /* ringbuffer.c in Sources */, 4BA3398010B2E36800190E3B /* JackAudioDriver.cpp in Sources */, 4BA3398110B2E36800190E3B /* JackFreewheelDriver.cpp in Sources */, 4BA3398210B2E36800190E3B /* JackThreadedDriver.cpp in Sources */, 4BA3398310B2E36800190E3B /* JackDriver.cpp in Sources */, 4BA3398410B2E36800190E3B /* JackDriverLoader.cpp in Sources */, 4BA3398510B2E36800190E3B /* JackEngine.cpp in Sources */, 4BA3398610B2E36800190E3B /* JackExternalClient.cpp in Sources */, 4BA3398710B2E36800190E3B /* JackInternalClient.cpp in Sources */, 4BA3398910B2E36800190E3B /* JackServer.cpp in Sources */, 4BA3398E10B2E36800190E3B /* JackTransportEngine.cpp in Sources */, 4BA3398F10B2E36800190E3B /* JackServerAPI.cpp in Sources */, 4BA3399010B2E36800190E3B /* JackServerGlobals.cpp in Sources */, 4BA3399110B2E36800190E3B /* timestamps.c in Sources */, 4BA3399210B2E36800190E3B /* JackPortType.cpp in Sources */, 4BA3399310B2E36800190E3B /* JackAudioPort.cpp in Sources */, 4BA3399410B2E36800190E3B /* JackMidiPort.cpp in Sources */, 4BA3399510B2E36800190E3B /* JackMidiAPI.cpp in Sources */, 4BA3399610B2E36800190E3B /* JackEngineControl.cpp in Sources */, 4BA3399710B2E36800190E3B /* JackDebugClient.cpp in Sources */, 4BA3399810B2E36800190E3B /* JackTools.cpp in Sources */, 4BA3399910B2E36800190E3B /* JackNetTool.cpp in Sources */, 4BA3399A10B2E36800190E3B /* JackError.cpp in Sources */, 4BA3399B10B2E36800190E3B /* JackMessageBuffer.cpp in Sources */, 4BA3399C10B2E36800190E3B /* JackRestartThreadedDriver.cpp in Sources */, 4BA3399D10B2E36800190E3B /* JackControlAPI.cpp in Sources */, 4BA3399E10B2E36800190E3B /* JackPosixThread.cpp in Sources */, 4BA3399F10B2E36800190E3B /* JackMachTime.c in Sources */, 4BA339A010B2E36800190E3B /* JackEngineProfiling.cpp in Sources */, 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */, 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */, 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */, 4BC2CA5D113C6CC90076717C /* JackNetInterface.cpp in Sources */, 4BC2CA5F113C6CD10076717C /* JackNetUnixSocket.cpp in Sources */, 4B6FE13B13DDABE700B4B943 /* JackSocketServerNotifyChannel.cpp in Sources */, 4B6FE13D13DDABFA00B4B943 /* JackSocketServerChannel.cpp in Sources */, 4B6FE13F13DDAC0C00B4B943 /* JackSocketNotifyChannel.cpp in Sources */, 4B6FE14413DDAC4700B4B943 /* JackSocket.cpp in Sources */, 4B6FE14D13DDACCC00B4B943 /* JackMidiAsyncQueue.cpp in Sources */, 4B6FE15313DDACEF00B4B943 /* JackMidiBufferWriteQueue.cpp in Sources */, 4B6FE15C13DDAD4600B4B943 /* JackMidiWriteQueue.cpp in Sources */, 4B6FE15E13DDAD5300B4B943 /* JackMidiUtil.cpp in Sources */, 4B6FE16013DDAD5F00B4B943 /* JackMidiSendQueue.cpp in Sources */, 4B6FE16213DDAD6F00B4B943 /* JackMidiReceiveQueue.cpp in Sources */, 4B6FE16413DDAD7F00B4B943 /* JackMidiReadQueue.cpp in Sources */, 4B6FE16613DDAD8F00B4B943 /* JackMidiBufferReadQueue.cpp in Sources */, 4B6FE16813DDAD9F00B4B943 /* JackMidiAsyncWaitQueue.cpp in Sources */, 4B21795313E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */, 4B67AB8F14B4B03800B4AA9A /* JackException.cpp in Sources */, 4B327BA914B4B50400976483 /* JackPosixMutex.cpp in Sources */, 4B1499F214BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, 4B90669C14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, 4BB4215B14D2C0A700A1CAE1 /* JackPosixProcessSync.cpp in Sources */, 4B4C3B6E1BC2FFDD0004CC35 /* JackPosixSemaphore.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BA692A80CBE4BC700EAD520 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BA692B30CBE4C2D00EAD520 /* ipload.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BA692CC0CBE4C9000EAD520 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BA692D70CBE4CC600EAD520 /* ipunload.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BA7FEBB0D8E76270017FF73 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BA7FECA0D8E76650017FF73 /* control.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BD623F00CBCF0F000DE782F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BD6240D0CBCF16600DE782F /* inprocess.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDB961001FB9C00B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDB971001FB9C00B15929 /* JackCoreMidiDriver.cpp in Sources */, 4B370A34133DD7E300237B68 /* JackCoreMidiInputPort.cpp in Sources */, 4B370A36133DD7E300237B68 /* JackCoreMidiOutputPort.cpp in Sources */, 4B370A38133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.cpp in Sources */, 4B370A3A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp in Sources */, 4B370A3C133DD7E300237B68 /* JackCoreMidiPort.cpp in Sources */, 4B370A3E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, 4B370A40133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, 4B370A42133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBBC1001FCC000B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDBBD1001FCC000B15929 /* JackNetDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBDD1001FD2D00B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDBDE1001FD2D00B15929 /* JackNetManager.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDBF31001FD7300B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDBF41001FD7300B15929 /* JackAudioAdapter.cpp in Sources */, 4BDCDBF51001FD7300B15929 /* JackAudioAdapterInterface.cpp in Sources */, 4BDCDBF61001FD7300B15929 /* JackLibSampleRateResampler.cpp in Sources */, 4BDCDBF71001FD7300B15929 /* JackResampler.cpp in Sources */, 4BDCDBF81001FD7300B15929 /* JackAudioAdapterFactory.cpp in Sources */, 4BDCDBF91001FD7300B15929 /* JackCoreAudioAdapter.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDCDC181001FDE300B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BDCDC191001FDE300B15929 /* JackAudioAdapterInterface.cpp in Sources */, 4BDCDC1A1001FDE300B15929 /* JackLibSampleRateResampler.cpp in Sources */, 4BDCDC1B1001FDE300B15929 /* JackResampler.cpp in Sources */, 4BDCDC1C1001FDE300B15929 /* JackNetAdapter.cpp in Sources */, 4BDCDC1E1001FDE300B15929 /* JackAudioAdapter.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BE6C6950A3E096F005A203A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BE6C6AD0A3E0A65005A203A /* test.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BE99D280AD7A04800C59091 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B3F49080AD8503300491C6E /* cpu.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BF339050F8B864B0080FB5B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BF3391B0F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */, 4B370A24133DD7E300237B68 /* JackCoreMidiInputPort.cpp in Sources */, 4B370A26133DD7E300237B68 /* JackCoreMidiOutputPort.cpp in Sources */, 4B370A28133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.cpp in Sources */, 4B370A2A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp in Sources */, 4B370A2C133DD7E300237B68 /* JackCoreMidiPort.cpp in Sources */, 4B370A2E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, 4B370A30133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, 4B370A32133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA5E8D0DEC4D9C00FA4CDB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFA5E9F0DEC4DD900FA4CDB /* testMutex.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82840DF6A9E40087B4E1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFA82850DF6A9E40087B4E1 /* evmon.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82970DF6A9E40087B4E1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFA82980DF6A9E40087B4E1 /* bufsize.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82A30DF6A9E40087B4E1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFA82A40DF6A9E40087B4E1 /* capture_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82AF0DF6A9E40087B4E1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFA82B00DF6A9E40087B4E1 /* monitor_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82BB0DF6A9E40087B4E1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFA82BC0DF6A9E40087B4E1 /* showtime.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA82C70DF6A9E40087B4E1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFA82C80DF6A9E40087B4E1 /* impulse_grabber.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFA999A0AAAF3B0009E916C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B3814201327AA6800C61B14 /* iodelay.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; BA222AC80DC88132001A17F4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( BA222ADE0DC882A5001A17F4 /* JackNetDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; BA222AE20DC882DB001A17F4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( BA222AED0DC883B3001A17F4 /* JackNetManager.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 4B0A28F40D520D11002EFF74 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B0A28DC0D52073D002EFF74 /* jack_thread_wait */; targetProxy = 4B0A28F30D520D11002EFF74 /* PBXContainerItemProxy */; }; 4B0A29300D5210C4002EFF74 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B0A29230D52108E002EFF74 /* jack_thread_wait 64 bits */; targetProxy = 4B0A292F0D5210C4002EFF74 /* PBXContainerItemProxy */; }; 4B19B32C0E23636E00DD4A82 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */; targetProxy = 4B19B32B0E23636E00DD4A82 /* PBXContainerItemProxy */; }; 4B20220C133A9C370019E213 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B2021DC133A9BA40019E213 /* jack_midi_latency 64 bits */; targetProxy = 4B20220B133A9C370019E213 /* PBXContainerItemProxy */; }; 4B224B340E65BA330066BE5B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */; targetProxy = 4B224B330E65BA330066BE5B /* PBXContainerItemProxy */; }; 4B3224E710A3157900838A8E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B3224D710A3156800838A8E /* jack_netone Universal */; targetProxy = 4B3224E610A3157900838A8E /* PBXContainerItemProxy */; }; 4B32258B10A31A9000838A8E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B32255710A3187800838A8E /* jack_netsource Universal */; targetProxy = 4B32258A10A31A9000838A8E /* PBXContainerItemProxy */; }; 4B32258D10A31A9D00838A8E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B3224D710A3156800838A8E /* jack_netone Universal */; targetProxy = 4B32258C10A31A9D00838A8E /* PBXContainerItemProxy */; }; 4B32258F10A31AB400838A8E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B32257110A3190C00838A8E /* jack_netsource 64 bits */; targetProxy = 4B32258E10A31AB400838A8E /* PBXContainerItemProxy */; }; 4B32259110A31ABA00838A8E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B32251D10A316B200838A8E /* jack_netone 64 bits */; targetProxy = 4B32259010A31ABA00838A8E /* PBXContainerItemProxy */; }; 4B35C5530D4731D2000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699D03097D421600A18468 /* jack_external_metro Universal */; targetProxy = 4B35C5540D4731D2000DE7AE /* PBXContainerItemProxy */; }; 4B35C67E0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */; targetProxy = 4B35C67D0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6800D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C4270D4731D1000DE7AE /* Jackmp.framework 64 bits */; targetProxy = 4B35C67F0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6820D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C4850D4731D1000DE7AE /* Jackservermp.framework 64 bits */; targetProxy = 4B35C6810D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6860D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */; targetProxy = 4B35C6850D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6880D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5160D4731D1000DE7AE /* jack_midisine 64 bits */; targetProxy = 4B35C6870D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C68A0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5220D4731D1000DE7AE /* jack_metro 64 bits */; targetProxy = 4B35C6890D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C68C0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C52E0D4731D1000DE7AE /* jack_lsp 64 bits */; targetProxy = 4B35C68B0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C68E0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C53A0D4731D1000DE7AE /* jack_connect 64 bits */; targetProxy = 4B35C68D0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6900D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5460D4731D1000DE7AE /* jack_disconnect 64 bits */; targetProxy = 4B35C68F0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6920D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5520D4731D2000DE7AE /* jack_freewheel 64 bits */; targetProxy = 4B35C6910D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6940D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5600D4731D2000DE7AE /* jack_iodelay 64 bits */; targetProxy = 4B35C6930D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6960D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C56C0D4731D2000DE7AE /* jack_external_metro 64 bits */; targetProxy = 4B35C6950D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C69C0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C59C0D4731D2000DE7AE /* zombie 64 bits */; targetProxy = 4B35C69B0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C69E0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5A80D4731D2000DE7AE /* jack_test 64 bits */; targetProxy = 4B35C69D0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6A00D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5B40D4731D2000DE7AE /* jack_cpu 64 bits */; targetProxy = 4B35C69F0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6A20D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5C00D4731D2000DE7AE /* jack_load 64 bits */; targetProxy = 4B35C6A10D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6A40D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C5CC0D4731D2000DE7AE /* jack_unload 64 bits */; targetProxy = 4B35C6A30D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6AC0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C6140D4731D2000DE7AE /* jack_coreaudio 64 bits */; targetProxy = 4B35C6AB0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6B00D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C62A0D4731D2000DE7AE /* jack_dummy 64 bits */; targetProxy = 4B35C6AF0D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6B20D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C6350D4731D3000DE7AE /* inprocess 64 bits */; targetProxy = 4B35C6B10D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B363DE50DEB037F001F72D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B363DCE0DEB02F6001F72D9 /* jack_alias Universal */; targetProxy = 4B363DE40DEB037F001F72D9 /* PBXContainerItemProxy */; }; 4B363E750DEB0838001F72D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B363E100DEB03C5001F72D9 /* jack_evmon Universal */; targetProxy = 4B363E740DEB0838001F72D9 /* PBXContainerItemProxy */; }; 4B363E770DEB0838001F72D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B363E440DEB0775001F72D9 /* jack_bufsize Universal */; targetProxy = 4B363E760DEB0838001F72D9 /* PBXContainerItemProxy */; }; 4B363F250DEB0ABE001F72D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */; targetProxy = 4B363F240DEB0ABE001F72D9 /* PBXContainerItemProxy */; }; 4B363F530DEB0CFE001F72D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */; targetProxy = 4B363F520DEB0CFE001F72D9 /* PBXContainerItemProxy */; }; 4B363F780DEB0D85001F72D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */; targetProxy = 4B363F770DEB0D85001F72D9 /* PBXContainerItemProxy */; }; 4B38120113269CB600C61B14 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B3811551326878E00C61B14 /* jack_latent_client Universal */; targetProxy = 4B38120013269CB600C61B14 /* PBXContainerItemProxy */; }; 4B38120313269CCB00C61B14 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B38118D1326884E00C61B14 /* jack_latent_client 64 bits */; targetProxy = 4B38120213269CCB00C61B14 /* PBXContainerItemProxy */; }; 4B43A8CD1014607100E52943 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B43A8B010145F6F00E52943 /* jack_loopback Universal */; targetProxy = 4B43A8CC1014607100E52943 /* PBXContainerItemProxy */; }; 4B43A8E91014618D00E52943 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */; targetProxy = 4B43A8E81014618D00E52943 /* PBXContainerItemProxy */; }; 4B5A1BCF0CD1CCC80005BF74 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */; targetProxy = 4B5A1BCE0CD1CCC80005BF74 /* PBXContainerItemProxy */; }; 4B5A1BE20CD1CD730005BF74 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B5A1BD00CD1CCE10005BF74 /* jack_midisine Universal */; targetProxy = 4B5A1BE10CD1CD730005BF74 /* PBXContainerItemProxy */; }; 4B66550E127C356E00753A79 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B6654ED127C34AE00753A79 /* jack_server_control 64 bits */; targetProxy = 4B66550D127C356E00753A79 /* PBXContainerItemProxy */; }; 4B699DB4097D421700A18468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699C4C097D421600A18468 /* Jackservermp.framework Universal */; targetProxy = 4B699DB3097D421700A18468 /* PBXContainerItemProxy */; }; 4B699DB6097D421700A18468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699C00097D421600A18468 /* Jackmp.framework Universal */; targetProxy = 4B699DB5097D421700A18468 /* PBXContainerItemProxy */; }; 4B699DB8097D421700A18468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699BA7097D421600A18468 /* jackdmp framework Universal */; targetProxy = 4B699DB7097D421700A18468 /* PBXContainerItemProxy */; }; 4B699DBA097D421700A18468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699D97097D421700A18468 /* jack_coreaudio Universal */; targetProxy = 4B699DB9097D421700A18468 /* PBXContainerItemProxy */; }; 4B699DBC097D421700A18468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699DA6097D421700A18468 /* jack_dummy Universal */; targetProxy = 4B699DBB097D421700A18468 /* PBXContainerItemProxy */; }; 4B699DC0097D421700A18468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699D03097D421600A18468 /* jack_external_metro Universal */; targetProxy = 4B699DBF097D421700A18468 /* PBXContainerItemProxy */; }; 4B8F16FA132916910002AD73 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B8F16DB13290DC80002AD73 /* jack_midi_dump Universal */; targetProxy = 4B8F16F9132916910002AD73 /* PBXContainerItemProxy */; }; 4B8F16FC1329169F0002AD73 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B8F16E813290E0E0002AD73 /* jack_midi_dump 64 bits */; targetProxy = 4B8F16FB1329169F0002AD73 /* PBXContainerItemProxy */; }; 4BA693E90CBE5BBA00EAD520 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BA692A60CBE4BC700EAD520 /* jack_load Universal */; targetProxy = 4BA693E80CBE5BBA00EAD520 /* PBXContainerItemProxy */; }; 4BA693EB0CBE5BBA00EAD520 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BA692CA0CBE4C9000EAD520 /* jack_unload Universal */; targetProxy = 4BA693EA0CBE5BBA00EAD520 /* PBXContainerItemProxy */; }; 4BA7FECD0D8E76810017FF73 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BA7FEB90D8E76270017FF73 /* jack_server_control Universal */; targetProxy = 4BA7FECC0D8E76810017FF73 /* PBXContainerItemProxy */; }; 4BAA1A7614CA08FE003269AD /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C61F0D4731D2000DE7AE /* jack_portaudio 64 bits */; targetProxy = 4BAA1A7514CA08FE003269AD /* PBXContainerItemProxy */; }; 4BB492A71372A393005F2601 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B8692821371DB4700D2D11B /* Jacknet.framework 64 bits */; targetProxy = 4BB492A61372A393005F2601 /* PBXContainerItemProxy */; }; 4BD624D30CBCF55700DE782F /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BD623ED0CBCF0F000DE782F /* inprocess Universal */; targetProxy = 4BD624D20CBCF55700DE782F /* PBXContainerItemProxy */; }; 4BDCDC2C1002036100B15929 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BDCDB931001FB9C00B15929 /* jack_coremidi 64 bits */; targetProxy = 4BDCDC2B1002036100B15929 /* PBXContainerItemProxy */; }; 4BDCDC2E1002036100B15929 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BDCDBB71001FCC000B15929 /* jack_net 64 bits */; targetProxy = 4BDCDC2D1002036100B15929 /* PBXContainerItemProxy */; }; 4BDCDC301002036100B15929 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BDCDBD71001FD2D00B15929 /* netmanager 64 bits */; targetProxy = 4BDCDC2F1002036100B15929 /* PBXContainerItemProxy */; }; 4BDCDC39100203D500B15929 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BDCDBEC1001FD7300B15929 /* audioadapter 64 bits */; targetProxy = 4BDCDC38100203D500B15929 /* PBXContainerItemProxy */; }; 4BDCDC3B100203D500B15929 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */; targetProxy = 4BDCDC3A100203D500B15929 /* PBXContainerItemProxy */; }; 4BE99D630AD7A19100C59091 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BE99D260AD7A04800C59091 /* jack_cpu Universal */; targetProxy = 4BE99D620AD7A19100C59091 /* PBXContainerItemProxy */; }; 4BF339280F8B87800080FB5B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BF339020F8B864B0080FB5B /* jack_coremidi Universal */; targetProxy = 4BF339270F8B87800080FB5B /* PBXContainerItemProxy */; }; 4BFA83320DF6AB540087B4E1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */; targetProxy = 4BFA83310DF6AB540087B4E1 /* PBXContainerItemProxy */; }; 4BFA83340DF6AB540087B4E1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BFA82950DF6A9E40087B4E1 /* jack_bufsize 64 bits */; targetProxy = 4BFA83330DF6AB540087B4E1 /* PBXContainerItemProxy */; }; 4BFA83380DF6AB540087B4E1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */; targetProxy = 4BFA83370DF6AB540087B4E1 /* PBXContainerItemProxy */; }; 4BFA833A0DF6AB540087B4E1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */; targetProxy = 4BFA83390DF6AB540087B4E1 /* PBXContainerItemProxy */; }; 4BFA833C0DF6AB540087B4E1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */; targetProxy = 4BFA833B0DF6AB540087B4E1 /* PBXContainerItemProxy */; }; 4BFA99440AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699CB1097D421600A18468 /* jack_metro Universal */; targetProxy = 4BFA99430AAAED90009E916C /* PBXContainerItemProxy */; }; 4BFA99460AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699CC1097D421600A18468 /* jack_lsp Universal */; targetProxy = 4BFA99450AAAED90009E916C /* PBXContainerItemProxy */; }; 4BFA99480AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699CD1097D421600A18468 /* jack_connect Universal */; targetProxy = 4BFA99470AAAED90009E916C /* PBXContainerItemProxy */; }; 4BFA994A0AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699CE1097D421600A18468 /* jack_disconnect Universal */; targetProxy = 4BFA99490AAAED90009E916C /* PBXContainerItemProxy */; }; 4BFA994C0AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699CF1097D421600A18468 /* jack_freewheel Universal */; targetProxy = 4BFA994B0AAAED90009E916C /* PBXContainerItemProxy */; }; 4BFA994E0AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699D03097D421600A18468 /* jack_external_metro Universal */; targetProxy = 4BFA994D0AAAED90009E916C /* PBXContainerItemProxy */; }; 4BFA99540AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699D3F097D421600A18468 /* zombie Universal */; targetProxy = 4BFA99530AAAED90009E916C /* PBXContainerItemProxy */; }; 4BFA99560AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BE6C6910A3E096F005A203A /* jack_test Universal */; targetProxy = 4BFA99550AAAED90009E916C /* PBXContainerItemProxy */; }; 4BFA99AC0AAAF41D009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BFA99980AAAF3B0009E916C /* jack_iodelay Universal */; targetProxy = 4BFA99AB0AAAF41D009E916C /* PBXContainerItemProxy */; }; BA222AF00DC883EF001A17F4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = BA222AE00DC882DB001A17F4 /* netmanager Universal */; targetProxy = BA222AEF0DC883EF001A17F4 /* PBXContainerItemProxy */; }; BA222AF20DC883F3001A17F4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = BA222AC50DC88132001A17F4 /* jack_net Universal */; targetProxy = BA222AF10DC883F3001A17F4 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 4B0A28E30D52073D002EFF74 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_thread_wait; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B0A28E40D52073D002EFF74 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_thread_wait; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B0A28E50D52073D002EFF74 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_thread_wait; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B0A292A0D52108E002EFF74 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_thread_wait; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B0A292B0D52108E002EFF74 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_thread_wait; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B0A292C0D52108E002EFF74 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_thread_wait; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B19B2FD0E23620F00DD4A82 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = i386; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ../macosx, /opt/local/include, ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = audioadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B19B2FE0E23620F00DD4A82 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ../macosx, /opt/local/include, ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = audioadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B19B2FF0E23620F00DD4A82 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B2021E3133A9BA40019E213 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midi_latency_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B2021E4133A9BA40019E213 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midi_latency_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B2021E5133A9BA40019E213 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B3224E210A3156800838A8E /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_netone; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B3224E310A3156800838A8E /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_netone; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B3224E410A3156800838A8E /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_CELT_API_0_7", "-DHAVE_CELT", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B32252810A316B200838A8E /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_netone; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B32252910A316B200838A8E /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_netone; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B32252A10A316B200838A8E /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B32255E10A3187800838A8E /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../macosx, ../common, ); OTHER_CFLAGS = ( "-DNO_JACK_ERROR", "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", ); OTHER_CPLUSPLUSFLAGS = ( "-DNO_JACK_ERROR", "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", ); OTHER_LDFLAGS = ( libcelt.a, "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_netsource; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B32255F10A3187800838A8E /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( ../macosx, ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DNO_JACK_ERROR", "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", ); OTHER_CPLUSPLUSFLAGS = ( "-DNO_JACK_ERROR", "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", ); OTHER_LDFLAGS = ( libcelt.a, "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_netsource; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B32256010A3187800838A8E /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", "$(OTHER_CFLAGS)", ); OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B32257810A3190C00838A8E /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../macosx, ../common, ); OTHER_CFLAGS = ( "-DNO_JACK_ERROR", "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", ); OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( libcelt.a, "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_netsource; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B32257910A3190C00838A8E /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( ../macosx, ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DNO_JACK_ERROR", "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", ); OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( libcelt.a, "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_netsource; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B32257A10A3190C00838A8E /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ( "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", "$(OTHER_CFLAGS)", ); OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C4220D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, RPC, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jackdmp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C4230D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, RPC, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jackdmp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C4240D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ../common, RPC, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", ); OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jackdmp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C4800D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DUSE_CLASSIC_AUTOLAUNCH", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = YES; }; name = Development; }; 4B35C4810D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_SSE3_EXTENSIONS = YES; GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DUSE_CLASSIC_AUTOLAUNCH", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; 4B35C4820D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; }; name = Default; }; 4B35C4F90D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DSERVER_SIDE", "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DSERVER_SIDE", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( libopus.a, "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackservermp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = YES; }; name = Development; }; 4B35C4FA0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_SSE3_EXTENSIONS = YES; GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DSERVER_SIDE", "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DSERVER_SIDE", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( libopus.a, "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackservermp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; 4B35C4FB0D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackdmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; }; name = Default; }; 4B35C5110D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5120D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5130D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C51D0D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C51E0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C51F0D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5290D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C52A0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C52B0D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5350D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_lsp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5360D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_lsp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5370D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_lsp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5410D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_connect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; SYMROOT = build; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5420D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_connect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; SYMROOT = build; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5430D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_connect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; SYMROOT = build; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C54D0D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_disconnect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C54E0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_disconnect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C54F0D4731D1000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_disconnect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C55B0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_freewheel; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C55C0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_freewheel; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C55D0D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_freewheel; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5670D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_iodelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5680D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_iodelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5690D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jdelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5730D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_external_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5740D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_external_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5750D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_external_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5830D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; HEADER_SEARCH_PATHS = ( ../common, ../posix, ., RPC, ); OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testAtomic; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5840D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; HEADER_SEARCH_PATHS = ( ../common, ../posix, ., RPC, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testAtomic; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5850D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; HEADER_SEARCH_PATHS = RPC; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testAtomic; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5970D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ../posix, ., ); OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testSem; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5980D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ( ../common, ../posix, ., ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testSem; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5990D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; GCC_OPTIMIZATION_LEVEL = 3; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testSem; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5A30D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = zombie; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5A40D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = zombie; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5A50D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = zombie; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5AF0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5B00D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5B10D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5BB0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_cpu; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5BC0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_cpu; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5BD0D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_cpu; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5C70D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_load; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5C80D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_load; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5C90D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_load; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5D30D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_unload; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5D40D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_unload; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5D50D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_unload; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5E70D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../posix, ., ../common, ); OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServer; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5E80D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServer; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5E90D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServer; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C5FB0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../posix, ., ../common, ); OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C5FC0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( ../posix, ., ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C5FD0D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C60F0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../posix, ., ../common, ); OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServerClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C6100D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( ../posix, ., ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServerClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C6110D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServerClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C61B0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ../common/jack, ../posix, ., ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( libaften_static.a, libaften_pcm.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coreaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C61C0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ../common/jack, ../posix, ., ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( libaften_pcm.a, libaften_static.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coreaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C61D0D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coreaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C6260D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common/; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( libportaudio.a, "-framework", Jackservermp, "-framework", AudioToolbox, "-framework", CoreAudio, "-framework", AudioUnit, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_portaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C6270D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common/; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( libportaudio.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", AudioUnit, "-framework", CoreServices, "-framework", AudioToolbox, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_portaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C6280D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common/; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( libportaudio.a, "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", AudioUnit, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_portaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C6310D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ../common/jack, ../posix, ., ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C6320D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; HEADER_SEARCH_PATHS = ( ../common, ../common/jack, ../posix, ., ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C6330D4731D2000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C63B0D4731D3000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C63C0D4731D3000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C63D0D4731D3000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc64, ppc, i386, x86_64, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B35C67A0D47339B000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = All; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B35C67B0D47339B000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = All; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B35C67C0D47339B000DE7AE /* Default */ = { isa = XCBuildConfiguration; buildSettings = { OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = All; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B363DD50DEB02F6001F72D9 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_alias; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B363DD60DEB02F6001F72D9 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_alias; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B363DD70DEB02F6001F72D9 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B363E170DEB03C5001F72D9 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_evmon; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B363E180DEB03C5001F72D9 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_evmon; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B363E190DEB03C5001F72D9 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B363E4B0DEB0775001F72D9 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_bufsize; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B363E4C0DEB0775001F72D9 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_bufsize; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B363E4D0DEB0775001F72D9 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B363EE60DEB091C001F72D9 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( /opt/local/include, ../common, ); LIBRARY_SEARCH_PATHS = /opt/local/lib; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( /opt/local/lib/libsndfile.a, "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_rec; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B363EE70DEB091C001F72D9 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( /opt/local/include, ../common, ); LIBRARY_SEARCH_PATHS = /opt/local/lib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( /opt/local/lib/libsndfile.a, "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_rec; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B363EE80DEB091C001F72D9 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B363F1B0DEB0A6A001F72D9 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_monitor_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B363F1C0DEB0A6A001F72D9 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_monitor_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B363F1D0DEB0A6A001F72D9 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B363F320DEB0BD1001F72D9 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_showtime; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B363F330DEB0BD1001F72D9 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_showtime; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B363F340DEB0BD1001F72D9 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B363F6F0DEB0D4E001F72D9 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_impulse_grabber; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B363F700DEB0D4E001F72D9 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_impulse_grabber; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B363F710DEB0D4E001F72D9 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B38115C1326878E00C61B14 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_latent_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B38115D1326878E00C61B14 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; LIBRARY_SEARCH_PATHS = ""; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_latent_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B38115E1326878E00C61B14 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B3811941326884E00C61B14 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_latent_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B3811951326884E00C61B14 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_latent_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B3811961326884E00C61B14 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B43A8B710145F6F00E52943 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ../common/jack, ., ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_loopback; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B43A8B810145F6F00E52943 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; HEADER_SEARCH_PATHS = ( ../common, ../common/jack, ., ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_loopback; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B43A8B910145F6F00E52943 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B43A8E41014615800E52943 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ../common/jack, ., ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_loopback; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B43A8E51014615800E52943 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; HEADER_SEARCH_PATHS = ( ../common, ../common/jack, ., ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_loopback; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B43A8E61014615800E52943 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B47ACD410B5890100469C67 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DUSE_CLASSIC_AUTOLAUNCH", "-D__CLIENTDEBUG__", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = YES; }; name = Development; }; 4B47ACD510B5890100469C67 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_SSE3_EXTENSIONS = YES; GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DUSE_CLASSIC_AUTOLAUNCH", "-D__CLIENTDEBUG__", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; 4B47ACD610B5890100469C67 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; }; name = Default; }; 4B5A1BB80CD1CB9E0005BF74 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B5A1BB90CD1CB9E0005BF74 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B5A1BBA0CD1CB9E0005BF74 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B5A1BD70CD1CCE10005BF74 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B5A1BD80CD1CCE10005BF74 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B5A1BD90CD1CCE10005BF74 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B5E08D20E5B66EE00BEE4E0 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = i386; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( /opt/local/include, ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_CELT", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = netadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B5E08D30E5B66EE00BEE4E0 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( /opt/local/include, ., ../posix, ../common, ../common/jack, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_CELT", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = netadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B5E08D40E5B66EE00BEE4E0 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B6654F4127C34AE00753A79 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackservermp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_server_control; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B6654F5127C34AE00753A79 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackservermp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_server_control; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B6654F6127C34AE00753A79 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699B34097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = All; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699B35097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = All; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699B36097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = All; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699BAE097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, RPC, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jackdmp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699BAF097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, RPC, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jackdmp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699BB0097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ../common, RPC, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", ); OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jackdmp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699C44097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DUSE_CLASSIC_AUTOLAUNCH", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = YES; }; name = Development; }; 4B699C45097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_SSE3_EXTENSIONS = YES; GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DUSE_CLASSIC_AUTOLAUNCH", "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; 4B699C46097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; }; name = Default; }; 4B699CA9097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DSERVER_SIDE", "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DSERVER_SIDE", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( libopus.a, "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackservermp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = YES; }; name = Development; }; 4B699CAA097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_SSE3_EXTENSIONS = YES; GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DSERVER_SIDE", "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DSERVER_SIDE", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( libopus.a, "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackservermp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; 4B699CAB097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackdmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; }; name = Default; }; 4B699CB8097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699CB9097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699CBA097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699CC8097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_lsp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699CC9097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_lsp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699CCA097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_lsp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699CD8097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_connect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; SYMROOT = build; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699CD9097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_connect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; SYMROOT = build; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699CDA097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_connect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; SYMROOT = build; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699CE8097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_disconnect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699CE9097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_disconnect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699CEA097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_disconnect; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699CFA097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_freewheel; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699CFB097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_freewheel; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699CFC097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_freewheel; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699D0A097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_external_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699D0B097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_external_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699D0C097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_external_metro; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699D1E097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, RPC, ); OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testAtomic; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699D1F097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, RPC, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testAtomic; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699D20097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; HEADER_SEARCH_PATHS = RPC; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testAtomic; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699D36097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ., ../common, ../common/jack, ../posix, ); OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testSem; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699D37097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ( ., ../common, ../common/jack, ../posix, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testSem; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699D38097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_OPTIMIZATION_LEVEL = 3; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testSem; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699D46097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = zombie; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699D47097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = zombie; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699D48097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = zombie; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699D5E097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServer; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699D5F097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServer; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699D60097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServer; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699D76097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699D77097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699D78097D421600A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699D8E097D421700A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServerClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699D8F097D421700A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServerClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699D90097D421700A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = synchroServerClient; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699D9E097D421700A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( libaften_static.a, libaften_pcm.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coreaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699D9F097D421700A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( libaften_static.a, libaften_pcm.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coreaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699DA0097D421700A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coreaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699DAD097D421700A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ../common/jack, ., ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B699DAE097D421700A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; HEADER_SEARCH_PATHS = ( ../common, ../common/jack, ., ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B699DAF097D421700A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B699DD6097D427F00A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Development; }; 4B699DD7097D427F00A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Deployment; }; 4B699DD8097D427F00A18468 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Default; }; 4B8692D81371DB4700D2D11B /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( /opt/local/include, ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = ( /opt/local/lib, /usr/lib/gcc/darwin/3.3, ); OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( libopus.a, /opt/local/lib/libsamplerate.a, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jacknet; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = YES; }; name = Development; }; 4B8692D91371DB4700D2D11B /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_SSE3_EXTENSIONS = YES; GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( /opt/local/include, ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = ( /opt/local/lib, /usr/lib/gcc/darwin/3.3, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_LDFLAGS = ( libopus.a, /opt/local/lib/libsamplerate.a, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jacknet; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; 4B8692DA1371DB4700D2D11B /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; }; name = Default; }; 4B8F16E213290DC80002AD73 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midi_dump; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B8F16E313290DC80002AD73 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midi_dump; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B8F16E413290DC80002AD73 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B8F16EF13290E0E0002AD73 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midi_dump; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B8F16F013290E0E0002AD73 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midi_dump; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B8F16F113290E0E0002AD73 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midisine; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4B978DB80A31CF4A009E2DD1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common/; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( libportaudio.a, "-framework", Jackservermp, "-framework", AudioToolbox, "-framework", CoreAudio, "-framework", AudioUnit, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_portaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4B978DB90A31CF4A009E2DD1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common/; INSTALL_PATH = /usr/local/lib; LD_OPENMP_FLAGS = "-fopenmp"; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( libportaudio.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", AudioUnit, "-framework", CoreServices, "-framework", AudioToolbox, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_portaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4B978DBA0A31CF4A009E2DD1 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common/; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( libportaudio.a, "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", AudioUnit, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_portaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BA339A910B2E36800190E3B /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DJACK_MONITOR", "-DSERVER_SIDE", "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DJACK_MONITOR", "-DSERVER_SIDE", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( libopus.a, "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackservermp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = YES; }; name = Development; }; 4BA339AA10B2E36800190E3B /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_SSE3_EXTENSIONS = YES; GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( ../common, ../posix, RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DJACK_MONITOR", "-DSERVER_SIDE", "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DJACK_MONITOR", "-DSERVER_SIDE", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( libopus.a, "-framework", Carbon, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackservermp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; 4BA339AB10B2E36800190E3B /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; FRAMEWORK_VERSION = A; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; GCC_WARN_UNKNOWN_PRAGMAS = NO; GENERATE_PKGINFO_FILE = NO; HEADER_SEARCH_PATHS = ( RPC, ../common/jack, ); INFOPLIST_FILE = "Jack-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = Jackdmp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost"; }; name = Default; }; 4BA692AD0CBE4BC700EAD520 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_load; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BA692AE0CBE4BC700EAD520 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_load; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BA692AF0CBE4BC700EAD520 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_load; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BA692D10CBE4C9000EAD520 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_unload; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BA692D20CBE4C9000EAD520 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_unload; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BA692D30CBE4C9000EAD520 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_unload; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BA7FEC00D8E76270017FF73 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_server_control; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BA7FEC10D8E76270017FF73 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackservermp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_server_control; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BA7FEC20D8E76270017FF73 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_lsp; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BD623F40CBCF0F000DE782F /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BD623F50CBCF0F000DE782F /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BD623F60CBCF0F000DE782F /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BDCDB9A1001FB9C00B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreMIDI, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coremidi; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BDCDB9B1001FB9C00B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreMIDI, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coremidi; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BDCDB9C1001FB9C00B15929 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coreaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BDCDBC21001FCC000B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_net; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BDCDBC31001FCC000B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_net; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BDCDBC41001FCC000B15929 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BDCDBE51001FD2D00B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = netmanager; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BDCDBE61001FD2D00B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "$(OTHER_CFLAGS)", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = netmanager; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BDCDBE71001FD2D00B15929 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BDCDBFC1001FD7300B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, x86_64, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ../macosx, /opt/local/include, ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = audioadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BDCDBFD1001FD7300B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, x86_64, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ../macosx, /opt/local/include, ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", "$(OTHER_CFLAGS)", ); OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = audioadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BDCDBFE1001FD7300B15929 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, x86_64, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BDCDC221001FDE300B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, x86_64, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( /opt/local/include, ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_CELT", "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = netadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BDCDC231001FDE300B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, x86_64, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( /opt/local/include, ., ../posix, ../common, ../common/jack, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_CELT", "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = netadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BDCDC241001FDE300B15929 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, x86_64, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BE6C6A00A3E096F005A203A /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BE6C6A10A3E096F005A203A /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BE6C6A20A3E096F005A203A /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( ppc, i386, ); GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BE99D2D0AD7A04800C59091 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_cpu; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BE99D2E0AD7A04800C59091 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_cpu; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BE99D2F0AD7A04800C59091 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_cpu; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BF339090F8B864B0080FB5B /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreMIDI, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coremidi; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BF3390A0F8B864B0080FB5B /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../common/jack, ../posix, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreMIDI, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coremidi; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BF3390B0F8B864B0080FB5B /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_coreaudio; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BFA5E950DEC4D9C00FA4CDB /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testSem; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BFA5E960DEC4D9C00FA4CDB /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testMutex; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BFA5E970DEC4D9C00FA4CDB /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; GCC_OPTIMIZATION_LEVEL = 3; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", AudioToolBox, "-framework", CoreAudio, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = testSem; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BFA82890DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_evmon; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BFA828A0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_evmon; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BFA828B0DF6A9E40087B4E1 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BFA829C0DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_bufsize; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BFA829D0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_bufsize; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BFA829E0DF6A9E40087B4E1 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BFA82A80DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( /opt/local/include, ../common, ); LIBRARY_SEARCH_PATHS = /opt/local/lib; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( /opt/local/lib/libsndfile.a, "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_rec; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BFA82A90DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( /opt/local/include, ../common, ); LIBRARY_SEARCH_PATHS = /opt/local/lib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( /opt/local/lib/libsndfile.a, "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_rec; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BFA82AA0DF6A9E40087B4E1 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BFA82B40DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_monitor_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BFA82B50DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_monitor_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BFA82B60DF6A9E40087B4E1 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BFA82C00DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_showtime; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BFA82C10DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_showtime; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BFA82C20DF6A9E40087B4E1 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BFA82CC0DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_impulse_grabber; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BFA82CD0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_impulse_grabber; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BFA82CE0DF6A9E40087B4E1 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, "-framework", CoreFoundation, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_midiseq; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; 4BFA999F0AAAF3B0009E916C /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_iodelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; 4BFA99A00AAAF3B0009E916C /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jack_iodelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; 4BFA99A10AAAF3B0009E916C /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, ); OTHER_REZFLAGS = ""; PRODUCT_NAME = jdelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; BA222ACC0DC88132001A17F4 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_net; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; BA222ACD0DC88132001A17F4 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; HEADER_SEARCH_PATHS = ( ../common, ., ../common/jack, ../posix, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = ( "-DHAVE_OPUS", "-DMACH_RPC_MACH_SEMA", ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreServices, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_net; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; BA222ACE0DC88132001A17F4 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; BA222AE60DC882DB001A17F4 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = netmanager; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = YES; }; name = Development; }; BA222AE70DC882DB001A17F4 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( ., ../posix, ../common/jack, ../common, ); INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = netmanager; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); ZERO_LINK = NO; }; name = Deployment; }; BA222AE80DC882DB001A17F4 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXECUTABLE_EXTENSION = so; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ../common; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", Jackdmp, "-framework", AudioToolBox, "-framework", CoreAudio, "-framework", CoreServices, "-framework", AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = inprocess; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", "-Wno-unknown-pragmas", ); }; name = Default; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 4B0A28E20D52073D002EFF74 /* Build configuration list for PBXNativeTarget "jack_thread_wait" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B0A28E30D52073D002EFF74 /* Development */, 4B0A28E40D52073D002EFF74 /* Deployment */, 4B0A28E50D52073D002EFF74 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B0A29290D52108E002EFF74 /* Build configuration list for PBXNativeTarget "jack_thread_wait 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B0A292A0D52108E002EFF74 /* Development */, 4B0A292B0D52108E002EFF74 /* Deployment */, 4B0A292C0D52108E002EFF74 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B19B2FC0E23620F00DD4A82 /* Build configuration list for PBXNativeTarget "audioadapter Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B19B2FD0E23620F00DD4A82 /* Development */, 4B19B2FE0E23620F00DD4A82 /* Deployment */, 4B19B2FF0E23620F00DD4A82 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B2021E2133A9BA40019E213 /* Build configuration list for PBXNativeTarget "jack_midi_latency 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B2021E3133A9BA40019E213 /* Development */, 4B2021E4133A9BA40019E213 /* Deployment */, 4B2021E5133A9BA40019E213 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B3224E110A3156800838A8E /* Build configuration list for PBXNativeTarget "jack_netone Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B3224E210A3156800838A8E /* Development */, 4B3224E310A3156800838A8E /* Deployment */, 4B3224E410A3156800838A8E /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B32252710A316B200838A8E /* Build configuration list for PBXNativeTarget "jack_netone 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B32252810A316B200838A8E /* Development */, 4B32252910A316B200838A8E /* Deployment */, 4B32252A10A316B200838A8E /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B32255D10A3187800838A8E /* Build configuration list for PBXNativeTarget "jack_netsource Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B32255E10A3187800838A8E /* Development */, 4B32255F10A3187800838A8E /* Deployment */, 4B32256010A3187800838A8E /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B32257710A3190C00838A8E /* Build configuration list for PBXNativeTarget "jack_netsource 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B32257810A3190C00838A8E /* Development */, 4B32257910A3190C00838A8E /* Deployment */, 4B32257A10A3190C00838A8E /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C4210D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jackdmp framework 64bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C4220D4731D1000DE7AE /* Development */, 4B35C4230D4731D1000DE7AE /* Deployment */, 4B35C4240D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C47F0D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "Jackmp.framework 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C4800D4731D1000DE7AE /* Development */, 4B35C4810D4731D1000DE7AE /* Deployment */, 4B35C4820D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C4F80D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "Jackservermp.framework 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C4F90D4731D1000DE7AE /* Development */, 4B35C4FA0D4731D1000DE7AE /* Deployment */, 4B35C4FB0D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5100D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_midiseq 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5110D4731D1000DE7AE /* Development */, 4B35C5120D4731D1000DE7AE /* Deployment */, 4B35C5130D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C51C0D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_midisine 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C51D0D4731D1000DE7AE /* Development */, 4B35C51E0D4731D1000DE7AE /* Deployment */, 4B35C51F0D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5280D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_metro 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5290D4731D1000DE7AE /* Development */, 4B35C52A0D4731D1000DE7AE /* Deployment */, 4B35C52B0D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5340D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_lsp 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5350D4731D1000DE7AE /* Development */, 4B35C5360D4731D1000DE7AE /* Deployment */, 4B35C5370D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5400D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_connect 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5410D4731D1000DE7AE /* Development */, 4B35C5420D4731D1000DE7AE /* Deployment */, 4B35C5430D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C54C0D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jack_disconnect 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C54D0D4731D1000DE7AE /* Development */, 4B35C54E0D4731D1000DE7AE /* Deployment */, 4B35C54F0D4731D1000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C55A0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_freewheel 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C55B0D4731D2000DE7AE /* Development */, 4B35C55C0D4731D2000DE7AE /* Deployment */, 4B35C55D0D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5660D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_iodelay 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5670D4731D2000DE7AE /* Development */, 4B35C5680D4731D2000DE7AE /* Deployment */, 4B35C5690D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5720D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_external_metro 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5730D4731D2000DE7AE /* Development */, 4B35C5740D4731D2000DE7AE /* Deployment */, 4B35C5750D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5820D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "testAtomic 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5830D4731D2000DE7AE /* Development */, 4B35C5840D4731D2000DE7AE /* Deployment */, 4B35C5850D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5960D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "testSem 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5970D4731D2000DE7AE /* Development */, 4B35C5980D4731D2000DE7AE /* Deployment */, 4B35C5990D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5A20D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "zombie 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5A30D4731D2000DE7AE /* Development */, 4B35C5A40D4731D2000DE7AE /* Deployment */, 4B35C5A50D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5AE0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_test 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5AF0D4731D2000DE7AE /* Development */, 4B35C5B00D4731D2000DE7AE /* Deployment */, 4B35C5B10D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5BA0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_cpu 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5BB0D4731D2000DE7AE /* Development */, 4B35C5BC0D4731D2000DE7AE /* Deployment */, 4B35C5BD0D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5C60D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_load 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5C70D4731D2000DE7AE /* Development */, 4B35C5C80D4731D2000DE7AE /* Deployment */, 4B35C5C90D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5D20D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_unload 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5D30D4731D2000DE7AE /* Development */, 4B35C5D40D4731D2000DE7AE /* Deployment */, 4B35C5D50D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5E60D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "synchroServer 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5E70D4731D2000DE7AE /* Development */, 4B35C5E80D4731D2000DE7AE /* Deployment */, 4B35C5E90D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C5FA0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "synchroClient 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5FB0D4731D2000DE7AE /* Development */, 4B35C5FC0D4731D2000DE7AE /* Deployment */, 4B35C5FD0D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C60E0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "synchroServerClient 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C60F0D4731D2000DE7AE /* Development */, 4B35C6100D4731D2000DE7AE /* Deployment */, 4B35C6110D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C61A0D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_coreaudio 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C61B0D4731D2000DE7AE /* Development */, 4B35C61C0D4731D2000DE7AE /* Deployment */, 4B35C61D0D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C6250D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_portaudio 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C6260D4731D2000DE7AE /* Development */, 4B35C6270D4731D2000DE7AE /* Deployment */, 4B35C6280D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C6300D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_dummy 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C6310D4731D2000DE7AE /* Development */, 4B35C6320D4731D2000DE7AE /* Deployment */, 4B35C6330D4731D2000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C63A0D4731D3000DE7AE /* Build configuration list for PBXNativeTarget "inprocess 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C63B0D4731D3000DE7AE /* Development */, 4B35C63C0D4731D3000DE7AE /* Deployment */, 4B35C63D0D4731D3000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B35C6790D47339B000DE7AE /* Build configuration list for PBXAggregateTarget "All Universal 32/64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C67A0D47339B000DE7AE /* Development */, 4B35C67B0D47339B000DE7AE /* Deployment */, 4B35C67C0D47339B000DE7AE /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B363DD40DEB02F6001F72D9 /* Build configuration list for PBXNativeTarget "jack_alias Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B363DD50DEB02F6001F72D9 /* Development */, 4B363DD60DEB02F6001F72D9 /* Deployment */, 4B363DD70DEB02F6001F72D9 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B363E160DEB03C5001F72D9 /* Build configuration list for PBXNativeTarget "jack_evmon Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B363E170DEB03C5001F72D9 /* Development */, 4B363E180DEB03C5001F72D9 /* Deployment */, 4B363E190DEB03C5001F72D9 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B363E4A0DEB0775001F72D9 /* Build configuration list for PBXNativeTarget "jack_bufsize Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B363E4B0DEB0775001F72D9 /* Development */, 4B363E4C0DEB0775001F72D9 /* Deployment */, 4B363E4D0DEB0775001F72D9 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B363EE50DEB091C001F72D9 /* Build configuration list for PBXNativeTarget "jack_rec Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B363EE60DEB091C001F72D9 /* Development */, 4B363EE70DEB091C001F72D9 /* Deployment */, 4B363EE80DEB091C001F72D9 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B363F1A0DEB0A6A001F72D9 /* Build configuration list for PBXNativeTarget "jack_monitor_client Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B363F1B0DEB0A6A001F72D9 /* Development */, 4B363F1C0DEB0A6A001F72D9 /* Deployment */, 4B363F1D0DEB0A6A001F72D9 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B363F310DEB0BD1001F72D9 /* Build configuration list for PBXNativeTarget "jack_showtime Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B363F320DEB0BD1001F72D9 /* Development */, 4B363F330DEB0BD1001F72D9 /* Deployment */, 4B363F340DEB0BD1001F72D9 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B363F6E0DEB0D4E001F72D9 /* Build configuration list for PBXNativeTarget "jack_impulse_grabber Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B363F6F0DEB0D4E001F72D9 /* Development */, 4B363F700DEB0D4E001F72D9 /* Deployment */, 4B363F710DEB0D4E001F72D9 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B38115B1326878E00C61B14 /* Build configuration list for PBXNativeTarget "jack_latent_client Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B38115C1326878E00C61B14 /* Development */, 4B38115D1326878E00C61B14 /* Deployment */, 4B38115E1326878E00C61B14 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B3811931326884E00C61B14 /* Build configuration list for PBXNativeTarget "jack_latent_client 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B3811941326884E00C61B14 /* Development */, 4B3811951326884E00C61B14 /* Deployment */, 4B3811961326884E00C61B14 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B43A8B610145F6F00E52943 /* Build configuration list for PBXNativeTarget "jack_loopback Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B43A8B710145F6F00E52943 /* Development */, 4B43A8B810145F6F00E52943 /* Deployment */, 4B43A8B910145F6F00E52943 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B43A8E31014615800E52943 /* Build configuration list for PBXNativeTarget "jack_loopback 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B43A8E41014615800E52943 /* Development */, 4B43A8E51014615800E52943 /* Deployment */, 4B43A8E61014615800E52943 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B47ACD310B5890100469C67 /* Build configuration list for PBXNativeTarget "Jackmp.framework 64 bits debugging" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B47ACD410B5890100469C67 /* Development */, 4B47ACD510B5890100469C67 /* Deployment */, 4B47ACD610B5890100469C67 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B5A1BB70CD1CB9E0005BF74 /* Build configuration list for PBXNativeTarget "jack_midiseq Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B5A1BB80CD1CB9E0005BF74 /* Development */, 4B5A1BB90CD1CB9E0005BF74 /* Deployment */, 4B5A1BBA0CD1CB9E0005BF74 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B5A1BD60CD1CCE10005BF74 /* Build configuration list for PBXNativeTarget "jack_midisine Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B5A1BD70CD1CCE10005BF74 /* Development */, 4B5A1BD80CD1CCE10005BF74 /* Deployment */, 4B5A1BD90CD1CCE10005BF74 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B5E08D10E5B66EE00BEE4E0 /* Build configuration list for PBXNativeTarget "netadapter Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B5E08D20E5B66EE00BEE4E0 /* Development */, 4B5E08D30E5B66EE00BEE4E0 /* Deployment */, 4B5E08D40E5B66EE00BEE4E0 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B6654F3127C34AE00753A79 /* Build configuration list for PBXNativeTarget "jack_server_control 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B6654F4127C34AE00753A79 /* Development */, 4B6654F5127C34AE00753A79 /* Deployment */, 4B6654F6127C34AE00753A79 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699B33097D421600A18468 /* Build configuration list for PBXAggregateTarget "All Universal 32 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699B34097D421600A18468 /* Development */, 4B699B35097D421600A18468 /* Deployment */, 4B699B36097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699BAD097D421600A18468 /* Build configuration list for PBXNativeTarget "jackdmp framework Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699BAE097D421600A18468 /* Development */, 4B699BAF097D421600A18468 /* Deployment */, 4B699BB0097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699C43097D421600A18468 /* Build configuration list for PBXNativeTarget "Jackmp.framework Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699C44097D421600A18468 /* Development */, 4B699C45097D421600A18468 /* Deployment */, 4B699C46097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699CA8097D421600A18468 /* Build configuration list for PBXNativeTarget "Jackservermp.framework Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699CA9097D421600A18468 /* Development */, 4B699CAA097D421600A18468 /* Deployment */, 4B699CAB097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699CB7097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_metro Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699CB8097D421600A18468 /* Development */, 4B699CB9097D421600A18468 /* Deployment */, 4B699CBA097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699CC7097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_lsp Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699CC8097D421600A18468 /* Development */, 4B699CC9097D421600A18468 /* Deployment */, 4B699CCA097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699CD7097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_connect Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699CD8097D421600A18468 /* Development */, 4B699CD9097D421600A18468 /* Deployment */, 4B699CDA097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699CE7097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_disconnect Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699CE8097D421600A18468 /* Development */, 4B699CE9097D421600A18468 /* Deployment */, 4B699CEA097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699CF9097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_freewheel Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699CFA097D421600A18468 /* Development */, 4B699CFB097D421600A18468 /* Deployment */, 4B699CFC097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699D09097D421600A18468 /* Build configuration list for PBXNativeTarget "jack_external_metro Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699D0A097D421600A18468 /* Development */, 4B699D0B097D421600A18468 /* Deployment */, 4B699D0C097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699D1D097D421600A18468 /* Build configuration list for PBXNativeTarget "testAtomic Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699D1E097D421600A18468 /* Development */, 4B699D1F097D421600A18468 /* Deployment */, 4B699D20097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699D35097D421600A18468 /* Build configuration list for PBXNativeTarget "testSem Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699D36097D421600A18468 /* Development */, 4B699D37097D421600A18468 /* Deployment */, 4B699D38097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699D45097D421600A18468 /* Build configuration list for PBXNativeTarget "zombie Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699D46097D421600A18468 /* Development */, 4B699D47097D421600A18468 /* Deployment */, 4B699D48097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699D5D097D421600A18468 /* Build configuration list for PBXNativeTarget "synchroServer Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699D5E097D421600A18468 /* Development */, 4B699D5F097D421600A18468 /* Deployment */, 4B699D60097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699D75097D421600A18468 /* Build configuration list for PBXNativeTarget "synchroClient Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699D76097D421600A18468 /* Development */, 4B699D77097D421600A18468 /* Deployment */, 4B699D78097D421600A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699D8D097D421700A18468 /* Build configuration list for PBXNativeTarget "synchroServerClient Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699D8E097D421700A18468 /* Development */, 4B699D8F097D421700A18468 /* Deployment */, 4B699D90097D421700A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699D9D097D421700A18468 /* Build configuration list for PBXNativeTarget "jack_coreaudio Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699D9E097D421700A18468 /* Development */, 4B699D9F097D421700A18468 /* Deployment */, 4B699DA0097D421700A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699DAC097D421700A18468 /* Build configuration list for PBXNativeTarget "jack_dummy Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699DAD097D421700A18468 /* Development */, 4B699DAE097D421700A18468 /* Deployment */, 4B699DAF097D421700A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B699DD5097D427F00A18468 /* Build configuration list for PBXProject "Jackdmp" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B699DD6097D427F00A18468 /* Development */, 4B699DD7097D427F00A18468 /* Deployment */, 4B699DD8097D427F00A18468 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B8692D71371DB4700D2D11B /* Build configuration list for PBXNativeTarget "Jacknet.framework 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B8692D81371DB4700D2D11B /* Development */, 4B8692D91371DB4700D2D11B /* Deployment */, 4B8692DA1371DB4700D2D11B /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B8F16E113290DC80002AD73 /* Build configuration list for PBXNativeTarget "jack_midi_dump Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B8F16E213290DC80002AD73 /* Development */, 4B8F16E313290DC80002AD73 /* Deployment */, 4B8F16E413290DC80002AD73 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B8F16EE13290E0E0002AD73 /* Build configuration list for PBXNativeTarget "jack_midi_dump 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B8F16EF13290E0E0002AD73 /* Development */, 4B8F16F013290E0E0002AD73 /* Deployment */, 4B8F16F113290E0E0002AD73 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4B978DB70A31CF4A009E2DD1 /* Build configuration list for PBXNativeTarget "jack_portaudio Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B978DB80A31CF4A009E2DD1 /* Development */, 4B978DB90A31CF4A009E2DD1 /* Deployment */, 4B978DBA0A31CF4A009E2DD1 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BA339A810B2E36800190E3B /* Build configuration list for PBXNativeTarget "Jackservermp.framework 64 bits profiling" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BA339A910B2E36800190E3B /* Development */, 4BA339AA10B2E36800190E3B /* Deployment */, 4BA339AB10B2E36800190E3B /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BA692AC0CBE4BC700EAD520 /* Build configuration list for PBXNativeTarget "jack_load Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BA692AD0CBE4BC700EAD520 /* Development */, 4BA692AE0CBE4BC700EAD520 /* Deployment */, 4BA692AF0CBE4BC700EAD520 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BA692D00CBE4C9000EAD520 /* Build configuration list for PBXNativeTarget "jack_unload Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BA692D10CBE4C9000EAD520 /* Development */, 4BA692D20CBE4C9000EAD520 /* Deployment */, 4BA692D30CBE4C9000EAD520 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BA7FEBF0D8E76270017FF73 /* Build configuration list for PBXNativeTarget "jack_server_control Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BA7FEC00D8E76270017FF73 /* Development */, 4BA7FEC10D8E76270017FF73 /* Deployment */, 4BA7FEC20D8E76270017FF73 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BD623F30CBCF0F000DE782F /* Build configuration list for PBXNativeTarget "inprocess Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BD623F40CBCF0F000DE782F /* Development */, 4BD623F50CBCF0F000DE782F /* Deployment */, 4BD623F60CBCF0F000DE782F /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BDCDB991001FB9C00B15929 /* Build configuration list for PBXNativeTarget "jack_coremidi 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BDCDB9A1001FB9C00B15929 /* Development */, 4BDCDB9B1001FB9C00B15929 /* Deployment */, 4BDCDB9C1001FB9C00B15929 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BDCDBC11001FCC000B15929 /* Build configuration list for PBXNativeTarget "jack_net 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BDCDBC21001FCC000B15929 /* Development */, 4BDCDBC31001FCC000B15929 /* Deployment */, 4BDCDBC41001FCC000B15929 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BDCDBE41001FD2D00B15929 /* Build configuration list for PBXNativeTarget "netmanager 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BDCDBE51001FD2D00B15929 /* Development */, 4BDCDBE61001FD2D00B15929 /* Deployment */, 4BDCDBE71001FD2D00B15929 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BDCDBFB1001FD7300B15929 /* Build configuration list for PBXNativeTarget "audioadapter 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BDCDBFC1001FD7300B15929 /* Development */, 4BDCDBFD1001FD7300B15929 /* Deployment */, 4BDCDBFE1001FD7300B15929 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BDCDC211001FDE300B15929 /* Build configuration list for PBXNativeTarget "netadapter 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BDCDC221001FDE300B15929 /* Development */, 4BDCDC231001FDE300B15929 /* Deployment */, 4BDCDC241001FDE300B15929 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BE6C69F0A3E096F005A203A /* Build configuration list for PBXNativeTarget "jack_test Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BE6C6A00A3E096F005A203A /* Development */, 4BE6C6A10A3E096F005A203A /* Deployment */, 4BE6C6A20A3E096F005A203A /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BE99D2C0AD7A04800C59091 /* Build configuration list for PBXNativeTarget "jack_cpu Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BE99D2D0AD7A04800C59091 /* Development */, 4BE99D2E0AD7A04800C59091 /* Deployment */, 4BE99D2F0AD7A04800C59091 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BF339080F8B864B0080FB5B /* Build configuration list for PBXNativeTarget "jack_coremidi Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BF339090F8B864B0080FB5B /* Development */, 4BF3390A0F8B864B0080FB5B /* Deployment */, 4BF3390B0F8B864B0080FB5B /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BFA5E940DEC4D9C00FA4CDB /* Build configuration list for PBXNativeTarget "testMutex Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA5E950DEC4D9C00FA4CDB /* Development */, 4BFA5E960DEC4D9C00FA4CDB /* Deployment */, 4BFA5E970DEC4D9C00FA4CDB /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BFA82880DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_evmon 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA82890DF6A9E40087B4E1 /* Development */, 4BFA828A0DF6A9E40087B4E1 /* Deployment */, 4BFA828B0DF6A9E40087B4E1 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BFA829B0DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_bufsize 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA829C0DF6A9E40087B4E1 /* Development */, 4BFA829D0DF6A9E40087B4E1 /* Deployment */, 4BFA829E0DF6A9E40087B4E1 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BFA82A70DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_rec 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA82A80DF6A9E40087B4E1 /* Development */, 4BFA82A90DF6A9E40087B4E1 /* Deployment */, 4BFA82AA0DF6A9E40087B4E1 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BFA82B30DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_monitor_client 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA82B40DF6A9E40087B4E1 /* Development */, 4BFA82B50DF6A9E40087B4E1 /* Deployment */, 4BFA82B60DF6A9E40087B4E1 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BFA82BF0DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_showtime 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA82C00DF6A9E40087B4E1 /* Development */, 4BFA82C10DF6A9E40087B4E1 /* Deployment */, 4BFA82C20DF6A9E40087B4E1 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BFA82CB0DF6A9E40087B4E1 /* Build configuration list for PBXNativeTarget "jack_impulse_grabber 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA82CC0DF6A9E40087B4E1 /* Development */, 4BFA82CD0DF6A9E40087B4E1 /* Deployment */, 4BFA82CE0DF6A9E40087B4E1 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; 4BFA999E0AAAF3B0009E916C /* Build configuration list for PBXNativeTarget "jack_iodelay Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA999F0AAAF3B0009E916C /* Development */, 4BFA99A00AAAF3B0009E916C /* Deployment */, 4BFA99A10AAAF3B0009E916C /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; BA222ACB0DC88132001A17F4 /* Build configuration list for PBXNativeTarget "jack_net Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( BA222ACC0DC88132001A17F4 /* Development */, BA222ACD0DC88132001A17F4 /* Deployment */, BA222ACE0DC88132001A17F4 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; BA222AE50DC882DB001A17F4 /* Build configuration list for PBXNativeTarget "netmanager Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( BA222AE60DC882DB001A17F4 /* Development */, BA222AE70DC882DB001A17F4 /* Deployment */, BA222AE80DC882DB001A17F4 /* Default */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; /* End XCConfigurationList section */ }; rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; } 1.9.12~dfsg/macosx/JackPlatformPlug_os.h0000644000000000000000000000534713214314510016722 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackPlatformPlug_APPLE__ #define __JackPlatformPlug_APPLE__ #include #define jack_server_dir "/tmp" #define jack_client_dir "/tmp" #define JACK_DEFAULT_DRIVER "coreaudio" namespace Jack { struct JackRequest; struct JackResult; class JackPosixMutex; class JackMachThread; class JackMachSemaphore; class JackSocketServerChannel; class JackSocketClientChannel; class JackSocketServerNotifyChannel; class JackSocketNotifyChannel; class JackNetUnixSocket; #ifdef MY_TARGET_OS_IPHONE class JackClient; class JackGraphManager; class JackEngineControl; class JackSynchro; #endif } /* __JackPlatformMutex__ */ #include "JackPosixMutex.h" namespace Jack { typedef JackPosixMutex JackMutex; } /* __JackPlatformThread__ */ #include "JackMachThread.h" namespace Jack { typedef JackMachThread JackThread; } /* __JackPlatformSynchro__ client activation */ #ifndef MY_TARGET_OS_IPHONE //#include "JackMachSemaphore.h" //namespace Jack { typedef JackMachSemaphore JackSynchro; } #include "JackPosixSemaphore.h" namespace Jack { typedef JackPosixSemaphore JackSynchro; } #endif /* __JackPlatformProcessSync__ */ #include "JackPosixProcessSync.h" namespace Jack { typedef JackPosixProcessSync JackProcessSync; } #ifndef MY_TARGET_OS_IPHONE /* __JackPlatformServerChannel__ */ #include "JackSocketServerChannel.h" namespace Jack { typedef JackSocketServerChannel JackServerChannel; } /* __JackPlatformClientChannel__ */ #include "JackSocketClientChannel.h" namespace Jack { typedef JackSocketClientChannel JackClientChannel; } /* __JackPlatformServerNotifyChannel__ */ #include "JackSocketServerNotifyChannel.h" namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; } /* __JackPlatformNotifyChannel__ */ #include "JackSocketNotifyChannel.h" namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; } #endif /* __JackPlatformNetSocket__ */ #include "JackNetUnixSocket.h" namespace Jack { typedef JackNetUnixSocket JackNetSocket; } #endif 1.9.12~dfsg/macosx/JackMachSemaphore.h0000644000000000000000000000347713214314510016323 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __JackMachSemaphore__ #define __JackMachSemaphore__ #include "JackCompilerDeps.h" #include "JackSynchro.h" #include #include #include namespace Jack { /*! \brief Inter process synchronization using using Mach semaphore. */ class SERVER_EXPORT JackMachSemaphore : public detail::JackSynchro { private: semaphore_t fSemaphore; mach_port_t fBootPort; protected: void BuildName(const char* name, const char* server_name, char* res, int size); public: JackMachSemaphore():JackSynchro(), fSemaphore(0), fBootPort(0) {} bool Signal(); bool SignalAll(); bool Wait(); bool TimedWait(long usec); bool Allocate(const char* name, const char* server_name, int value); bool Connect(const char* name, const char* server_name); bool ConnectInput(const char* name, const char* server_name); bool ConnectOutput(const char* name, const char* server_name); bool Disconnect(); void Destroy(); }; } // end of namespace #endif 1.9.12~dfsg/macosx/install_jackdmp0000755000000000000000000000461413214314510015724 0ustar rootroot# Install jackdmp and owerwrite JACK installation # Plug-ins [ -d Panda.framework ] && sudo cp -r Panda.framework /Library/Frameworks [ -d JackRouter.plugin ] && sudo cp -r JackRouter.plugin /Library/Audio/Plug-Ins/HAL/ # Copy libraries and exe sudo cp -r Jackmp.framework /Library/Frameworks/ sudo cp -r Jackservermp.framework /Library/Frameworks/ sudo cp -r Jacknet.framework /Library/Frameworks/ sudo install -d /usr/local/bin sudo cp jackdmp /usr/local/bin [ -f jack_load ] && sudo cp jack_load /usr/local/bin [ -f jack_unload ] && sudo cp jack_unload /usr/local/bin [ -f jack_netsource ] && sudo cp jack_netsource /usr/local/bin # Copy drivers sudo install -d /usr/local/lib/jackmp sudo cp jack_coreaudio.so /usr/local/lib/jackmp sudo cp jack_coremidi.so /usr/local/lib/jackmp sudo cp jack_dummy.so /usr/local/lib/jackmp sudo cp jack_loopback.so /usr/local/lib/jackmp [ -f jack_net.so ] && sudo cp jack_net.so /usr/local/lib/jackmp [ -f jack_netone.so ] && sudo cp jack_netone.so /usr/local/lib/jackmp # Copy tools [ -f netmanager.so ] && sudo cp netmanager.so /usr/local/lib/jackmp [ -f netadapter.so ] && sudo cp netadapter.so /usr/local/lib/jackmp [ -f audioadapter.so ] && sudo cp audioadapter.so /usr/local/lib/jackmp # Create links to jackmp ressources cd /usr/local/bin && [ -f jackd ] && sudo rm jackd cd /usr/local/lib && [ -f libjack.0.dylib ] && sudo rm libjack.0.dylib cd /usr/local/lib && [ -f libjack.dylib ] && sudo rm libjack.dylib cd /usr/local/lib && [ -f libjackserver.0.dylib ] && sudo rm libjackserver.0.dylib cd /usr/local/lib && [ -f libjackserver.dylib ] && sudo rm libjackserver.dylib cd /usr/local/lib && [ -f libjacknet.dylib ] && sudo rm libjacknet.dylib cd /usr/local/lib && [ -f libjacknet.0.dylib ] && sudo rm libjacknet.0.dylib cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jackmp.framework/Jackmp libjack.dylib cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jackmp.framework/Jackmp libjack.0.dylib cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jackservermp.framework/Jackservermp libjackserver.dylib cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jackservermp.framework/Jackservermp libjackserver.0.dylib cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jacknet.framework/Jacknet libjacknet.dylib cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jacknet.framework/Jacknet libjacknet.0.dylib cd /usr/local/bin && sudo ln -s jackdmp jackd 1.9.12~dfsg/macosx/JackMachThread.h0000644000000000000000000001352413214314510015601 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Copyright: Copyright 2002 Apple Computer, Inc. All rights reserved. Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this Apple software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this Apple software. In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under Apple copyrights in this original Apple software (the "Apple Software"), to use, reproduce, modify and redistribute the Apple Software, with or without modifications, in source and/or binary forms; provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software. Neither the name, trademarks, service marks or logos of Apple Computer, Inc. may be used to endorse or promote products derived from the Apple Software without specific prior written permission from Apple. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Apple herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the Apple Software may be incorporated. The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __JackMachThread__ #define __JackMachThread__ #include #ifdef MY_TARGET_OS_IPHONE typedef unsigned char Boolean; #endif #include "JackPosixThread.h" #ifndef MY_TARGET_OS_IPHONE #include #endif #include #include #ifndef MY_TARGET_OS_IPHONE #include #endif #define THREAD_SET_PRIORITY 0 #define THREAD_SCHEDULED_PRIORITY 1 namespace Jack { /*! \brief Darwin threads. Real-time threads are actually "time constraint" threads. */ class SERVER_EXPORT JackMachThread : public JackPosixThread { private: UInt64 fPeriod; UInt64 fComputation; UInt64 fConstraint; static UInt32 GetThreadSetPriority(jack_native_thread_t thread); static UInt32 GetThreadScheduledPriority(jack_native_thread_t thread); static UInt32 GetThreadPriority(jack_native_thread_t thread, int inWhichPriority); public: JackMachThread(JackRunnableInterface* runnable, UInt64 period, UInt64 computation, UInt64 constraint) : JackPosixThread(runnable), fPeriod(period), fComputation(computation), fConstraint(constraint) {} JackMachThread(JackRunnableInterface* runnable, int cancellation = PTHREAD_CANCEL_ASYNCHRONOUS) : JackPosixThread(runnable, cancellation), fPeriod(0), fComputation(0), fConstraint(0) {} int Kill(); int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself void SetParams(UInt64 period, UInt64 computation, UInt64 constraint); static int GetParams(jack_native_thread_t thread, UInt64* period, UInt64* computation, UInt64* constraint); static int SetThreadToPriority(jack_native_thread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint); static int AcquireRealTimeImp(jack_native_thread_t thread, UInt64 period, UInt64 computation, UInt64 constraint); static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) { return JackMachThread::AcquireRealTimeImp(thread, period, computation, constraint); } static int DropRealTimeImp(jack_native_thread_t thread); }; } // end of namespace #endif 1.9.12~dfsg/macosx/JackMachSemaphore.mm0000644000000000000000000001457513214314510016506 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMachSemaphore.h" #include "JackConstants.h" #include "JackTools.h" #include "JackError.h" #include namespace Jack { void JackMachSemaphore::BuildName(const char* client_name, const char* server_name, char* res, int size) { char ext_client_name[SYNC_MAX_NAME_SIZE + 1]; JackTools::RewriteName(client_name, ext_client_name); snprintf(res, size, "jack_mach_sem.%d_%s_%s", JackTools::GetUID(), server_name, ext_client_name); } bool JackMachSemaphore::Signal() { if (!fSemaphore) { jack_error("JackMachSemaphore::Signal name = %s already deallocated!!", fName); return false; } if (fFlush) { return true; } kern_return_t res; if ((res = semaphore_signal(fSemaphore)) != KERN_SUCCESS) { jack_error("JackMachSemaphore::Signal name = %s err = %s", fName, mach_error_string(res)); } return (res == KERN_SUCCESS); } bool JackMachSemaphore::SignalAll() { if (!fSemaphore) { jack_error("JackMachSemaphore::SignalAll name = %s already deallocated!!", fName); return false; } if (fFlush) { return true; } kern_return_t res; // When signaled several times, do not accumulate signals... if ((res = semaphore_signal_all(fSemaphore)) != KERN_SUCCESS) { jack_error("JackMachSemaphore::SignalAll name = %s err = %s", fName, mach_error_string(res)); } return (res == KERN_SUCCESS); } bool JackMachSemaphore::Wait() { if (!fSemaphore) { jack_error("JackMachSemaphore::Wait name = %s already deallocated!!", fName); return false; } kern_return_t res; if ((res = semaphore_wait(fSemaphore)) != KERN_SUCCESS) { jack_error("JackMachSemaphore::Wait name = %s err = %s", fName, mach_error_string(res)); } return (res == KERN_SUCCESS); } bool JackMachSemaphore::TimedWait(long usec) { if (!fSemaphore) { jack_error("JackMachSemaphore::TimedWait name = %s already deallocated!!", fName); return false; } kern_return_t res; mach_timespec time; time.tv_sec = usec / 1000000; time.tv_nsec = (usec % 1000000) * 1000; if ((res = semaphore_timedwait(fSemaphore, time)) != KERN_SUCCESS) { jack_error("JackMachSemaphore::TimedWait name = %s usec = %ld err = %s", fName, usec, mach_error_string(res)); } return (res == KERN_SUCCESS); } // Server side : publish the semaphore in the global namespace bool JackMachSemaphore::Allocate(const char* name, const char* server_name, int value) { BuildName(name, server_name, fName, sizeof(fName)); mach_port_t task = mach_task_self(); kern_return_t res; if (fBootPort == 0) { if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) { jack_error("Allocate: Can't find bootstrap mach port err = %s", mach_error_string(res)); return false; } } if ((res = semaphore_create(task, &fSemaphore, SYNC_POLICY_FIFO, value)) != KERN_SUCCESS) { jack_error("Allocate: can create semaphore err = %s", mach_error_string(res)); return false; } if ((res = bootstrap_register(fBootPort, fName, fSemaphore)) != KERN_SUCCESS) { jack_error("Allocate: can't check in mach semaphore name = %s err = %s", fName, mach_error_string(res)); switch (res) { case BOOTSTRAP_SUCCESS : /* service not currently registered, "a good thing" (tm) */ break; case BOOTSTRAP_NOT_PRIVILEGED : jack_log("bootstrap_register(): bootstrap not privileged"); break; case BOOTSTRAP_SERVICE_ACTIVE : jack_log("bootstrap_register(): bootstrap service active"); break; default : jack_log("bootstrap_register() err = %s", mach_error_string(res)); break; } return false; } jack_log("JackMachSemaphore::Allocate name = %s", fName); return true; } // Client side : get the published semaphore from server bool JackMachSemaphore::ConnectInput(const char* name, const char* server_name) { BuildName(name, server_name, fName, sizeof(fName)); kern_return_t res; if (fBootPort == 0) { if ((res = task_get_bootstrap_port(mach_task_self(), &fBootPort)) != KERN_SUCCESS) { jack_error("Connect: can't find bootstrap port err = %s", mach_error_string(res)); return false; } } if ((res = bootstrap_look_up(fBootPort, fName, &fSemaphore)) != KERN_SUCCESS) { jack_error("Connect: can't find mach semaphore name = %s err = %s", fName, mach_error_string(res)); return false; } jack_log("JackMachSemaphore::Connect name = %s ", fName); return true; } bool JackMachSemaphore::Connect(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackMachSemaphore::ConnectOutput(const char* name, const char* server_name) { return ConnectInput(name, server_name); } bool JackMachSemaphore::Disconnect() { if (fSemaphore > 0) { jack_log("JackMachSemaphore::Disconnect name = %s", fName); fSemaphore = 0; } // Nothing to do return true; } // Server side : destroy the JackGlobals void JackMachSemaphore::Destroy() { kern_return_t res; if (fSemaphore > 0) { jack_log("JackMachSemaphore::Destroy name = %s", fName); if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) { jack_error("JackMachSemaphore::Destroy can't destroy semaphore err = %s", mach_error_string(res)); } fSemaphore = 0; } else { jack_error("JackMachSemaphore::Destroy semaphore < 0"); } } } // end of namespace 1.9.12~dfsg/macosx/iphone/0000755000000000000000000000000013214314510014114 5ustar rootroot1.9.12~dfsg/macosx/iphone/iPhoneNet_Prefix.pch0000644000000000000000000000033213214314510020014 0ustar rootroot// // Prefix header for all source files of the 'iPhoneNet' target in the 'iPhoneNet' project // #ifdef __OBJC__ #import #import #endif #define MY_TARGET_OS_IPHONE 1 1.9.12~dfsg/macosx/iphone/iphone-faust.mm0000644000000000000000000032103513214314510017055 0ustar rootroot//----------------------------------------------------- // name: "freeverb" // version: "1.0" // author: "Grame" // license: "BSD" // copyright: "(c)GRAME 2006" // // Code generated with Faust 0.9.10 (http://faust.grame.fr) //----------------------------------------------------- /* link with */ /* link with */ #include /* link with */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "HardwareClock.h" using namespace std; // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) // flags to avoid costly denormals #ifdef __SSE__ #include #ifdef __SSE2__ #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040) #else #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) #endif #else #define AVOIDDENORMALS #endif //#define BENCHMARKMODE struct Meta : map { void declare (const char* key, const char* value) { (*this)[key] = value; } }; //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); } // g++ -O3 -lm -ljack `gtk-config --cflags --libs` ex2.cpp #define max(x,y) (((x)>(y)) ? (x) : (y)) #define min(x,y) (((x)<(y)) ? (x) : (y)) inline int lsr(int x, int n) { return int(((unsigned int)x) >> n); } inline int int2pow2(int x) { int r=0; while ((1< fPrefix; map fKeyParam; void addOption(const char* label, float* zone, float init, float min, float max) { string fullname = fPrefix.top() + label; fKeyParam.insert(make_pair(fullname, param(zone, min, max))); *zone = init; } void openAnyBox(const char* label) { string prefix; if (label && label[0]) { prefix = fPrefix.top() + "-" + label; } else { prefix = fPrefix.top(); } fPrefix.push(prefix); } public: CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); } virtual ~CMDUI() {} virtual void addButton(const char* label, float* zone) {}; virtual void addToggleButton(const char* label, float* zone) {}; virtual void addCheckButton(const char* label, float* zone) {}; virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) { addOption(label,zone,init, min,max); } virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) { addOption(label,zone,init, min,max); } virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) { addOption(label,zone,init, min,max); } // -- passive widgets virtual void addNumDisplay(const char* label, float* zone, int precision) {} virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) {} virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) {} virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) {} virtual void openFrameBox(const char* label) { openAnyBox(label); } virtual void openTabBox(const char* label) { openAnyBox(label); } virtual void openHorizontalBox(const char* label) { openAnyBox(label); } virtual void openVerticalBox(const char* label) { openAnyBox(label); } virtual void closeBox() { fPrefix.pop(); } virtual void show() {} virtual void run() { char c; printf("Type 'q' to quit\n"); while ((c = getchar()) != 'q') { sleep(1); } } void print() { map::iterator i; cout << fArgc << "\n"; cout << fArgv[0] << " option list : "; for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) { cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] "; } } void process_command() { map::iterator p; for (int i = 1; i < fArgc; i++) { if (fArgv[i][0] == '-') { p = fKeyParam.find(fArgv[i]); if (p == fKeyParam.end()) { cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; print(); exit(1); } char* end; *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); i++; } } } void process_init() { map::iterator p; for (int i = 1; i < fArgc; i++) { if (fArgv[i][0] == '-') { p = fKeyParam.find(fArgv[i]); if (p == fKeyParam.end()) { cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; exit(1); } char* end; *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); i++; } } } }; /****************************************************************************** ******************************************************************************* FAUST DSP ******************************************************************************* *******************************************************************************/ //---------------------------------------------------------------- // abstract definition of a signal processor //---------------------------------------------------------------- class dsp { protected: int fSamplingFreq; public: dsp() {} virtual ~dsp() {} virtual int getNumInputs() = 0; virtual int getNumOutputs() = 0; virtual void buildUserInterface(UI* interface) = 0; virtual void init(int samplingRate) = 0; virtual void compute(int len, float** inputs, float** outputs) = 0; }; //---------------------------------------------------------------------------- // FAUST generated signal processor //---------------------------------------------------------------------------- #ifndef FAUSTFLOAT #define FAUSTFLOAT float #endif typedef long double quad; class mydsp : public dsp{ private: FAUSTFLOAT fslider0; float fRec9_perm[4]; FAUSTFLOAT fslider1; float fRec19_perm[4]; float fYec0[4096]; int fYec0_idx; int fYec0_idx_save; float fRec18_perm[4]; float fRec21_perm[4]; float fYec1[4096]; int fYec1_idx; int fYec1_idx_save; float fRec20_perm[4]; float fRec23_perm[4]; float fYec2[4096]; int fYec2_idx; int fYec2_idx_save; float fRec22_perm[4]; float fRec25_perm[4]; float fYec3[4096]; int fYec3_idx; int fYec3_idx_save; float fRec24_perm[4]; float fRec27_perm[4]; float fYec4[4096]; int fYec4_idx; int fYec4_idx_save; float fRec26_perm[4]; float fRec29_perm[4]; float fYec5[4096]; int fYec5_idx; int fYec5_idx_save; float fRec28_perm[4]; float fRec31_perm[4]; float fYec6[4096]; int fYec6_idx; int fYec6_idx_save; float fRec30_perm[4]; float fRec33_perm[4]; float fYec7[4096]; int fYec7_idx; int fYec7_idx_save; float fRec32_perm[4]; float fYec8[2048]; int fYec8_idx; int fYec8_idx_save; float fRec16_perm[4]; float fYec9[2048]; int fYec9_idx; int fYec9_idx_save; float fRec14_perm[4]; float fYec10[2048]; int fYec10_idx; int fYec10_idx_save; float fRec12_perm[4]; float fYec11[2048]; int fYec11_idx; int fYec11_idx_save; float fRec10_perm[4]; FAUSTFLOAT fslider2; float fRec43_perm[4]; float fYec12[4096]; int fYec12_idx; int fYec12_idx_save; float fRec42_perm[4]; float fRec45_perm[4]; float fYec13[4096]; int fYec13_idx; int fYec13_idx_save; float fRec44_perm[4]; float fRec47_perm[4]; float fYec14[4096]; int fYec14_idx; int fYec14_idx_save; float fRec46_perm[4]; float fRec49_perm[4]; float fYec15[4096]; int fYec15_idx; int fYec15_idx_save; float fRec48_perm[4]; float fRec51_perm[4]; float fYec16[4096]; int fYec16_idx; int fYec16_idx_save; float fRec50_perm[4]; float fRec53_perm[4]; float fYec17[4096]; int fYec17_idx; int fYec17_idx_save; float fRec52_perm[4]; float fRec55_perm[4]; float fYec18[4096]; int fYec18_idx; int fYec18_idx_save; float fRec54_perm[4]; float fRec57_perm[4]; float fYec19[4096]; int fYec19_idx; int fYec19_idx_save; float fRec56_perm[4]; float fYec20[2048]; int fYec20_idx; int fYec20_idx_save; float fRec40_perm[4]; float fYec21[2048]; int fYec21_idx; int fYec21_idx_save; float fRec38_perm[4]; float fYec22[2048]; int fYec22_idx; int fYec22_idx_save; float fRec36_perm[4]; float fYec23[2048]; int fYec23_idx; int fYec23_idx_save; float fRec34_perm[4]; float fYec24[4096]; int fYec24_idx; int fYec24_idx_save; float fRec8_perm[4]; float fRec59_perm[4]; float fYec25[4096]; int fYec25_idx; int fYec25_idx_save; float fRec58_perm[4]; float fRec61_perm[4]; float fYec26[4096]; int fYec26_idx; int fYec26_idx_save; float fRec60_perm[4]; float fRec63_perm[4]; float fYec27[4096]; int fYec27_idx; int fYec27_idx_save; float fRec62_perm[4]; float fRec65_perm[4]; float fYec28[4096]; int fYec28_idx; int fYec28_idx_save; float fRec64_perm[4]; float fRec67_perm[4]; float fYec29[4096]; int fYec29_idx; int fYec29_idx_save; float fRec66_perm[4]; float fRec69_perm[4]; float fYec30[4096]; int fYec30_idx; int fYec30_idx_save; float fRec68_perm[4]; float fRec71_perm[4]; float fYec31[4096]; int fYec31_idx; int fYec31_idx_save; float fRec70_perm[4]; float fYec32[2048]; int fYec32_idx; int fYec32_idx_save; float fRec6_perm[4]; float fYec33[2048]; int fYec33_idx; int fYec33_idx_save; float fRec4_perm[4]; float fYec34[2048]; int fYec34_idx; int fYec34_idx_save; float fRec2_perm[4]; float fYec35[2048]; int fYec35_idx; int fYec35_idx_save; float fRec0_perm[4]; float fRec81_perm[4]; float fYec36[4096]; int fYec36_idx; int fYec36_idx_save; float fRec80_perm[4]; float fRec83_perm[4]; float fYec37[4096]; int fYec37_idx; int fYec37_idx_save; float fRec82_perm[4]; float fRec85_perm[4]; float fYec38[4096]; int fYec38_idx; int fYec38_idx_save; float fRec84_perm[4]; float fRec87_perm[4]; float fYec39[4096]; int fYec39_idx; int fYec39_idx_save; float fRec86_perm[4]; float fRec89_perm[4]; float fYec40[4096]; int fYec40_idx; int fYec40_idx_save; float fRec88_perm[4]; float fRec91_perm[4]; float fYec41[4096]; int fYec41_idx; int fYec41_idx_save; float fRec90_perm[4]; float fRec93_perm[4]; float fYec42[4096]; int fYec42_idx; int fYec42_idx_save; float fRec92_perm[4]; float fRec95_perm[4]; float fYec43[4096]; int fYec43_idx; int fYec43_idx_save; float fRec94_perm[4]; float fYec44[2048]; int fYec44_idx; int fYec44_idx_save; float fRec78_perm[4]; float fYec45[2048]; int fYec45_idx; int fYec45_idx_save; float fRec76_perm[4]; float fYec46[2048]; int fYec46_idx; int fYec46_idx_save; float fRec74_perm[4]; float fYec47[2048]; int fYec47_idx; int fYec47_idx_save; float fRec72_perm[4]; public: static void metadata(Meta* m) { m->declare("name", "freeverb"); m->declare("version", "1.0"); m->declare("author", "Grame"); m->declare("license", "BSD"); m->declare("copyright", "(c)GRAME 2006"); } virtual int getNumInputs() { return 2; } virtual int getNumOutputs() { return 2; } static void classInit(int samplingFreq) { } virtual void instanceInit(int samplingFreq) { fSamplingFreq = samplingFreq; fslider0 = 0.5f; for (int i=0; i<4; i++) fRec9_perm[i]=0; fslider1 = 0.5f; for (int i=0; i<4; i++) fRec19_perm[i]=0; for (int i=0; i<4096; i++) fYec0[i]=0; fYec0_idx = 0; fYec0_idx_save = 0; for (int i=0; i<4; i++) fRec18_perm[i]=0; for (int i=0; i<4; i++) fRec21_perm[i]=0; for (int i=0; i<4096; i++) fYec1[i]=0; fYec1_idx = 0; fYec1_idx_save = 0; for (int i=0; i<4; i++) fRec20_perm[i]=0; for (int i=0; i<4; i++) fRec23_perm[i]=0; for (int i=0; i<4096; i++) fYec2[i]=0; fYec2_idx = 0; fYec2_idx_save = 0; for (int i=0; i<4; i++) fRec22_perm[i]=0; for (int i=0; i<4; i++) fRec25_perm[i]=0; for (int i=0; i<4096; i++) fYec3[i]=0; fYec3_idx = 0; fYec3_idx_save = 0; for (int i=0; i<4; i++) fRec24_perm[i]=0; for (int i=0; i<4; i++) fRec27_perm[i]=0; for (int i=0; i<4096; i++) fYec4[i]=0; fYec4_idx = 0; fYec4_idx_save = 0; for (int i=0; i<4; i++) fRec26_perm[i]=0; for (int i=0; i<4; i++) fRec29_perm[i]=0; for (int i=0; i<4096; i++) fYec5[i]=0; fYec5_idx = 0; fYec5_idx_save = 0; for (int i=0; i<4; i++) fRec28_perm[i]=0; for (int i=0; i<4; i++) fRec31_perm[i]=0; for (int i=0; i<4096; i++) fYec6[i]=0; fYec6_idx = 0; fYec6_idx_save = 0; for (int i=0; i<4; i++) fRec30_perm[i]=0; for (int i=0; i<4; i++) fRec33_perm[i]=0; for (int i=0; i<4096; i++) fYec7[i]=0; fYec7_idx = 0; fYec7_idx_save = 0; for (int i=0; i<4; i++) fRec32_perm[i]=0; for (int i=0; i<2048; i++) fYec8[i]=0; fYec8_idx = 0; fYec8_idx_save = 0; for (int i=0; i<4; i++) fRec16_perm[i]=0; for (int i=0; i<2048; i++) fYec9[i]=0; fYec9_idx = 0; fYec9_idx_save = 0; for (int i=0; i<4; i++) fRec14_perm[i]=0; for (int i=0; i<2048; i++) fYec10[i]=0; fYec10_idx = 0; fYec10_idx_save = 0; for (int i=0; i<4; i++) fRec12_perm[i]=0; for (int i=0; i<2048; i++) fYec11[i]=0; fYec11_idx = 0; fYec11_idx_save = 0; for (int i=0; i<4; i++) fRec10_perm[i]=0; fslider2 = 0.3333f; for (int i=0; i<4; i++) fRec43_perm[i]=0; for (int i=0; i<4096; i++) fYec12[i]=0; fYec12_idx = 0; fYec12_idx_save = 0; for (int i=0; i<4; i++) fRec42_perm[i]=0; for (int i=0; i<4; i++) fRec45_perm[i]=0; for (int i=0; i<4096; i++) fYec13[i]=0; fYec13_idx = 0; fYec13_idx_save = 0; for (int i=0; i<4; i++) fRec44_perm[i]=0; for (int i=0; i<4; i++) fRec47_perm[i]=0; for (int i=0; i<4096; i++) fYec14[i]=0; fYec14_idx = 0; fYec14_idx_save = 0; for (int i=0; i<4; i++) fRec46_perm[i]=0; for (int i=0; i<4; i++) fRec49_perm[i]=0; for (int i=0; i<4096; i++) fYec15[i]=0; fYec15_idx = 0; fYec15_idx_save = 0; for (int i=0; i<4; i++) fRec48_perm[i]=0; for (int i=0; i<4; i++) fRec51_perm[i]=0; for (int i=0; i<4096; i++) fYec16[i]=0; fYec16_idx = 0; fYec16_idx_save = 0; for (int i=0; i<4; i++) fRec50_perm[i]=0; for (int i=0; i<4; i++) fRec53_perm[i]=0; for (int i=0; i<4096; i++) fYec17[i]=0; fYec17_idx = 0; fYec17_idx_save = 0; for (int i=0; i<4; i++) fRec52_perm[i]=0; for (int i=0; i<4; i++) fRec55_perm[i]=0; for (int i=0; i<4096; i++) fYec18[i]=0; fYec18_idx = 0; fYec18_idx_save = 0; for (int i=0; i<4; i++) fRec54_perm[i]=0; for (int i=0; i<4; i++) fRec57_perm[i]=0; for (int i=0; i<4096; i++) fYec19[i]=0; fYec19_idx = 0; fYec19_idx_save = 0; for (int i=0; i<4; i++) fRec56_perm[i]=0; for (int i=0; i<2048; i++) fYec20[i]=0; fYec20_idx = 0; fYec20_idx_save = 0; for (int i=0; i<4; i++) fRec40_perm[i]=0; for (int i=0; i<2048; i++) fYec21[i]=0; fYec21_idx = 0; fYec21_idx_save = 0; for (int i=0; i<4; i++) fRec38_perm[i]=0; for (int i=0; i<2048; i++) fYec22[i]=0; fYec22_idx = 0; fYec22_idx_save = 0; for (int i=0; i<4; i++) fRec36_perm[i]=0; for (int i=0; i<2048; i++) fYec23[i]=0; fYec23_idx = 0; fYec23_idx_save = 0; for (int i=0; i<4; i++) fRec34_perm[i]=0; for (int i=0; i<4096; i++) fYec24[i]=0; fYec24_idx = 0; fYec24_idx_save = 0; for (int i=0; i<4; i++) fRec8_perm[i]=0; for (int i=0; i<4; i++) fRec59_perm[i]=0; for (int i=0; i<4096; i++) fYec25[i]=0; fYec25_idx = 0; fYec25_idx_save = 0; for (int i=0; i<4; i++) fRec58_perm[i]=0; for (int i=0; i<4; i++) fRec61_perm[i]=0; for (int i=0; i<4096; i++) fYec26[i]=0; fYec26_idx = 0; fYec26_idx_save = 0; for (int i=0; i<4; i++) fRec60_perm[i]=0; for (int i=0; i<4; i++) fRec63_perm[i]=0; for (int i=0; i<4096; i++) fYec27[i]=0; fYec27_idx = 0; fYec27_idx_save = 0; for (int i=0; i<4; i++) fRec62_perm[i]=0; for (int i=0; i<4; i++) fRec65_perm[i]=0; for (int i=0; i<4096; i++) fYec28[i]=0; fYec28_idx = 0; fYec28_idx_save = 0; for (int i=0; i<4; i++) fRec64_perm[i]=0; for (int i=0; i<4; i++) fRec67_perm[i]=0; for (int i=0; i<4096; i++) fYec29[i]=0; fYec29_idx = 0; fYec29_idx_save = 0; for (int i=0; i<4; i++) fRec66_perm[i]=0; for (int i=0; i<4; i++) fRec69_perm[i]=0; for (int i=0; i<4096; i++) fYec30[i]=0; fYec30_idx = 0; fYec30_idx_save = 0; for (int i=0; i<4; i++) fRec68_perm[i]=0; for (int i=0; i<4; i++) fRec71_perm[i]=0; for (int i=0; i<4096; i++) fYec31[i]=0; fYec31_idx = 0; fYec31_idx_save = 0; for (int i=0; i<4; i++) fRec70_perm[i]=0; for (int i=0; i<2048; i++) fYec32[i]=0; fYec32_idx = 0; fYec32_idx_save = 0; for (int i=0; i<4; i++) fRec6_perm[i]=0; for (int i=0; i<2048; i++) fYec33[i]=0; fYec33_idx = 0; fYec33_idx_save = 0; for (int i=0; i<4; i++) fRec4_perm[i]=0; for (int i=0; i<2048; i++) fYec34[i]=0; fYec34_idx = 0; fYec34_idx_save = 0; for (int i=0; i<4; i++) fRec2_perm[i]=0; for (int i=0; i<2048; i++) fYec35[i]=0; fYec35_idx = 0; fYec35_idx_save = 0; for (int i=0; i<4; i++) fRec0_perm[i]=0; for (int i=0; i<4; i++) fRec81_perm[i]=0; for (int i=0; i<4096; i++) fYec36[i]=0; fYec36_idx = 0; fYec36_idx_save = 0; for (int i=0; i<4; i++) fRec80_perm[i]=0; for (int i=0; i<4; i++) fRec83_perm[i]=0; for (int i=0; i<4096; i++) fYec37[i]=0; fYec37_idx = 0; fYec37_idx_save = 0; for (int i=0; i<4; i++) fRec82_perm[i]=0; for (int i=0; i<4; i++) fRec85_perm[i]=0; for (int i=0; i<4096; i++) fYec38[i]=0; fYec38_idx = 0; fYec38_idx_save = 0; for (int i=0; i<4; i++) fRec84_perm[i]=0; for (int i=0; i<4; i++) fRec87_perm[i]=0; for (int i=0; i<4096; i++) fYec39[i]=0; fYec39_idx = 0; fYec39_idx_save = 0; for (int i=0; i<4; i++) fRec86_perm[i]=0; for (int i=0; i<4; i++) fRec89_perm[i]=0; for (int i=0; i<4096; i++) fYec40[i]=0; fYec40_idx = 0; fYec40_idx_save = 0; for (int i=0; i<4; i++) fRec88_perm[i]=0; for (int i=0; i<4; i++) fRec91_perm[i]=0; for (int i=0; i<4096; i++) fYec41[i]=0; fYec41_idx = 0; fYec41_idx_save = 0; for (int i=0; i<4; i++) fRec90_perm[i]=0; for (int i=0; i<4; i++) fRec93_perm[i]=0; for (int i=0; i<4096; i++) fYec42[i]=0; fYec42_idx = 0; fYec42_idx_save = 0; for (int i=0; i<4; i++) fRec92_perm[i]=0; for (int i=0; i<4; i++) fRec95_perm[i]=0; for (int i=0; i<4096; i++) fYec43[i]=0; fYec43_idx = 0; fYec43_idx_save = 0; for (int i=0; i<4; i++) fRec94_perm[i]=0; for (int i=0; i<2048; i++) fYec44[i]=0; fYec44_idx = 0; fYec44_idx_save = 0; for (int i=0; i<4; i++) fRec78_perm[i]=0; for (int i=0; i<2048; i++) fYec45[i]=0; fYec45_idx = 0; fYec45_idx_save = 0; for (int i=0; i<4; i++) fRec76_perm[i]=0; for (int i=0; i<2048; i++) fYec46[i]=0; fYec46_idx = 0; fYec46_idx_save = 0; for (int i=0; i<4; i++) fRec74_perm[i]=0; for (int i=0; i<2048; i++) fYec47[i]=0; fYec47_idx = 0; fYec47_idx_save = 0; for (int i=0; i<4; i++) fRec72_perm[i]=0; } virtual void init(int samplingFreq) { classInit(samplingFreq); instanceInit(samplingFreq); } virtual void buildUserInterface(UI* interface) { interface->openVerticalBox("Freeverb"); interface->addHorizontalSlider("Damp", &fslider0, 0.5f, 0.0f, 1.0f, 2.500000e-02f); interface->addHorizontalSlider("RoomSize", &fslider1, 0.5f, 0.0f, 1.0f, 2.500000e-02f); interface->addHorizontalSlider("Wet", &fslider2, 0.3333f, 0.0f, 1.0f, 2.500000e-02f); interface->closeBox(); } virtual void compute (int fullcount, FAUSTFLOAT** input, FAUSTFLOAT** output) { float fRec9_tmp[1024+4]; float fRec19_tmp[1024+4]; float fZec0[1024]; float fRec18_tmp[1024+4]; float fRec21_tmp[1024+4]; float fRec20_tmp[1024+4]; float fRec23_tmp[1024+4]; float fRec22_tmp[1024+4]; float fRec25_tmp[1024+4]; float fRec24_tmp[1024+4]; float fRec27_tmp[1024+4]; float fRec26_tmp[1024+4]; float fRec29_tmp[1024+4]; float fRec28_tmp[1024+4]; float fRec31_tmp[1024+4]; float fRec30_tmp[1024+4]; float fRec33_tmp[1024+4]; float fRec32_tmp[1024+4]; float fZec1[1024]; float fRec16_tmp[1024+4]; float fRec17[1024]; float fRec14_tmp[1024+4]; float fRec15[1024]; float fRec12_tmp[1024+4]; float fRec13[1024]; float fRec10_tmp[1024+4]; float fRec11[1024]; float fZec2[1024]; float fRec43_tmp[1024+4]; float fRec42_tmp[1024+4]; float fRec45_tmp[1024+4]; float fRec44_tmp[1024+4]; float fRec47_tmp[1024+4]; float fRec46_tmp[1024+4]; float fRec49_tmp[1024+4]; float fRec48_tmp[1024+4]; float fRec51_tmp[1024+4]; float fRec50_tmp[1024+4]; float fRec53_tmp[1024+4]; float fRec52_tmp[1024+4]; float fRec55_tmp[1024+4]; float fRec54_tmp[1024+4]; float fRec57_tmp[1024+4]; float fRec56_tmp[1024+4]; float fZec3[1024]; float fRec40_tmp[1024+4]; float fRec41[1024]; float fRec38_tmp[1024+4]; float fRec39[1024]; float fRec36_tmp[1024+4]; float fRec37[1024]; float fRec34_tmp[1024+4]; float fRec35[1024]; float fZec4[1024]; float fZec5[1024]; float fRec8_tmp[1024+4]; float fRec59_tmp[1024+4]; float fRec58_tmp[1024+4]; float fRec61_tmp[1024+4]; float fRec60_tmp[1024+4]; float fRec63_tmp[1024+4]; float fRec62_tmp[1024+4]; float fRec65_tmp[1024+4]; float fRec64_tmp[1024+4]; float fRec67_tmp[1024+4]; float fRec66_tmp[1024+4]; float fRec69_tmp[1024+4]; float fRec68_tmp[1024+4]; float fRec71_tmp[1024+4]; float fRec70_tmp[1024+4]; float fZec6[1024]; float fRec6_tmp[1024+4]; float fRec7[1024]; float fRec4_tmp[1024+4]; float fRec5[1024]; float fRec2_tmp[1024+4]; float fRec3[1024]; float fRec0_tmp[1024+4]; float fRec1[1024]; float fRec81_tmp[1024+4]; float fRec80_tmp[1024+4]; float fRec83_tmp[1024+4]; float fRec82_tmp[1024+4]; float fRec85_tmp[1024+4]; float fRec84_tmp[1024+4]; float fRec87_tmp[1024+4]; float fRec86_tmp[1024+4]; float fRec89_tmp[1024+4]; float fRec88_tmp[1024+4]; float fRec91_tmp[1024+4]; float fRec90_tmp[1024+4]; float fRec93_tmp[1024+4]; float fRec92_tmp[1024+4]; float fRec95_tmp[1024+4]; float fRec94_tmp[1024+4]; float fZec7[1024]; float fRec78_tmp[1024+4]; float fRec79[1024]; float fRec76_tmp[1024+4]; float fRec77[1024]; float fRec74_tmp[1024+4]; float fRec75[1024]; float fRec72_tmp[1024+4]; float fRec73[1024]; float fSlow0 = (0.4f * fslider0); float fSlow1 = (1 - fSlow0); float* fRec9 = &fRec9_tmp[4]; float fSlow2 = (0.7f + (0.28f * fslider1)); float* fRec19 = &fRec19_tmp[4]; float* fRec18 = &fRec18_tmp[4]; float* fRec21 = &fRec21_tmp[4]; float* fRec20 = &fRec20_tmp[4]; float* fRec23 = &fRec23_tmp[4]; float* fRec22 = &fRec22_tmp[4]; float* fRec25 = &fRec25_tmp[4]; float* fRec24 = &fRec24_tmp[4]; float* fRec27 = &fRec27_tmp[4]; float* fRec26 = &fRec26_tmp[4]; float* fRec29 = &fRec29_tmp[4]; float* fRec28 = &fRec28_tmp[4]; float* fRec31 = &fRec31_tmp[4]; float* fRec30 = &fRec30_tmp[4]; float* fRec33 = &fRec33_tmp[4]; float* fRec32 = &fRec32_tmp[4]; float* fRec16 = &fRec16_tmp[4]; float* fRec14 = &fRec14_tmp[4]; float* fRec12 = &fRec12_tmp[4]; float* fRec10 = &fRec10_tmp[4]; float fSlow3 = fslider2; float fSlow4 = (1 - fSlow3); float* fRec43 = &fRec43_tmp[4]; float* fRec42 = &fRec42_tmp[4]; float* fRec45 = &fRec45_tmp[4]; float* fRec44 = &fRec44_tmp[4]; float* fRec47 = &fRec47_tmp[4]; float* fRec46 = &fRec46_tmp[4]; float* fRec49 = &fRec49_tmp[4]; float* fRec48 = &fRec48_tmp[4]; float* fRec51 = &fRec51_tmp[4]; float* fRec50 = &fRec50_tmp[4]; float* fRec53 = &fRec53_tmp[4]; float* fRec52 = &fRec52_tmp[4]; float* fRec55 = &fRec55_tmp[4]; float* fRec54 = &fRec54_tmp[4]; float* fRec57 = &fRec57_tmp[4]; float* fRec56 = &fRec56_tmp[4]; float* fRec40 = &fRec40_tmp[4]; float* fRec38 = &fRec38_tmp[4]; float* fRec36 = &fRec36_tmp[4]; float* fRec34 = &fRec34_tmp[4]; float* fRec8 = &fRec8_tmp[4]; float* fRec59 = &fRec59_tmp[4]; float* fRec58 = &fRec58_tmp[4]; float* fRec61 = &fRec61_tmp[4]; float* fRec60 = &fRec60_tmp[4]; float* fRec63 = &fRec63_tmp[4]; float* fRec62 = &fRec62_tmp[4]; float* fRec65 = &fRec65_tmp[4]; float* fRec64 = &fRec64_tmp[4]; float* fRec67 = &fRec67_tmp[4]; float* fRec66 = &fRec66_tmp[4]; float* fRec69 = &fRec69_tmp[4]; float* fRec68 = &fRec68_tmp[4]; float* fRec71 = &fRec71_tmp[4]; float* fRec70 = &fRec70_tmp[4]; float* fRec6 = &fRec6_tmp[4]; float* fRec4 = &fRec4_tmp[4]; float* fRec2 = &fRec2_tmp[4]; float* fRec0 = &fRec0_tmp[4]; float* fRec81 = &fRec81_tmp[4]; float* fRec80 = &fRec80_tmp[4]; float* fRec83 = &fRec83_tmp[4]; float* fRec82 = &fRec82_tmp[4]; float* fRec85 = &fRec85_tmp[4]; float* fRec84 = &fRec84_tmp[4]; float* fRec87 = &fRec87_tmp[4]; float* fRec86 = &fRec86_tmp[4]; float* fRec89 = &fRec89_tmp[4]; float* fRec88 = &fRec88_tmp[4]; float* fRec91 = &fRec91_tmp[4]; float* fRec90 = &fRec90_tmp[4]; float* fRec93 = &fRec93_tmp[4]; float* fRec92 = &fRec92_tmp[4]; float* fRec95 = &fRec95_tmp[4]; float* fRec94 = &fRec94_tmp[4]; float* fRec78 = &fRec78_tmp[4]; float* fRec76 = &fRec76_tmp[4]; float* fRec74 = &fRec74_tmp[4]; float* fRec72 = &fRec72_tmp[4]; int index; for (index = 0; index <= fullcount - 1024; index += 1024) { // compute by blocks of 1024 samples const int count = 1024; FAUSTFLOAT* input0 = &input[0][index]; FAUSTFLOAT* input1 = &input[1][index]; FAUSTFLOAT* output0 = &output[0][index]; FAUSTFLOAT* output1 = &output[1][index]; // SECTION : 1 // LOOP 0x101350bc0 // exec code for (int i=0; imSampleRate); printf(" Format ID:%.*s\n", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); printf(" Format Flags:%lX\n", inDesc->mFormatFlags); printf(" Bytes per Packet:%ld\n", inDesc->mBytesPerPacket); printf(" Frames per Packet:%ld\n", inDesc->mFramesPerPacket); printf(" Bytes per Frame:%ld\n", inDesc->mBytesPerFrame); printf(" Channels per Frame:%ld\n", inDesc->mChannelsPerFrame); printf(" Bits per Channel:%ld\n", inDesc->mBitsPerChannel); printf("- - - - - - - - - - - - - - - - - - - -\n"); } static void printError(OSStatus err) { switch (err) { case kAudioConverterErr_FormatNotSupported: printf("error code : kAudioConverterErr_FormatNotSupported\n"); break; case kAudioConverterErr_OperationNotSupported: printf("error code : kAudioConverterErr_OperationNotSupported\n"); break; case kAudioConverterErr_PropertyNotSupported: printf("error code : kAudioConverterErr_PropertyNotSupported\n"); break; case kAudioConverterErr_InvalidInputSize: printf("error code : kAudioConverterErr_InvalidInputSize\n"); break; case kAudioConverterErr_InvalidOutputSize: printf("error code : kAudioConverterErr_InvalidOutputSize\n"); break; case kAudioConverterErr_UnspecifiedError: printf("error code : kAudioConverterErr_UnspecifiedError\n"); break; case kAudioConverterErr_BadPropertySizeError: printf("error code : kAudioConverterErr_BadPropertySizeError\n"); break; case kAudioConverterErr_RequiresPacketDescriptionsError: printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n"); break; case kAudioConverterErr_InputSampleRateOutOfRange: printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n"); break; case kAudioConverterErr_OutputSampleRateOutOfRange: printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n"); break; default: printf("error code : unknown\n"); break; } } st::HardwareClock my_clock; OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32, UInt32 inNumberFrames, AudioBufferList *ioData) { TiPhoneCoreAudioRendererPtr renderer = (TiPhoneCoreAudioRendererPtr)inRefCon; my_clock.Update(); //printf("TiPhoneCoreAudioRenderer::Render 0 %d\n", inNumberFrames); AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData); float coef = 1.f/32768.f; /* for (int chan = 0; chan < fDevNumInChans; chan++) { for (int frame = 0; frame < inNumberFrames; frame++) { fInChannel[chan][frame] = float(((long*)ioData->mBuffers[chan].mData)[frame]) / 32768.f; fInChannel[chan][frame] = float(((long*)ioData->mBuffers[chan].mData)[frame]) / 32768.f; } } */ for (int frame = 0; frame < inNumberFrames; frame++) { float sample = float(((long*)ioData->mBuffers[0].mData)[frame]) * coef; renderer->fInChannel[0][frame] = sample; renderer->fInChannel[1][frame] = sample; } //printf("TiPhoneCoreAudioRenderer::Render 1 %d\n", inNumberFrames); DSP.compute((int)inNumberFrames, renderer->fInChannel, renderer->fOutChannel); for (int chan = 0; chan < renderer->fDevNumOutChans; chan++) { for (int frame = 0; frame < inNumberFrames; frame++) { ((long*)ioData->mBuffers[chan].mData)[frame] = long(renderer->fOutChannel[chan][frame] * 32768.f); } } my_clock.Update(); const float dt = my_clock.GetDeltaTime(); printf("Normal: %f s\n", dt); //printf("TiPhoneCoreAudioRenderer::Render 3 %d\n", inNumberFrames); return 0; } void TiPhoneCoreAudioRenderer::InterruptionListener(void *inClientData, UInt32 inInterruption) { printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); TiPhoneCoreAudioRenderer *obj = (TiPhoneCoreAudioRenderer*)inClientData; if (inInterruption == kAudioSessionEndInterruption) { // make sure we are again the active session AudioSessionSetActive(true); AudioOutputUnitStart(obj->fAUHAL); } if (inInterruption == kAudioSessionBeginInterruption) { AudioOutputUnitStop(obj->fAUHAL); } } long TiPhoneCoreAudioRenderer::Open(long bufferSize, long samplerate) { OSStatus err1; UInt32 outSize; UInt32 enableIO; Boolean isWritable; AudioStreamBasicDescription srcFormat, dstFormat; printf("Open fDevNumInChans = %ld fDevNumOutChans = %ld bufferSize = %ld samplerate = %ld\n", fDevNumInChans, fDevNumOutChans, bufferSize, samplerate); // Initialize and configure the audio session err1 = AudioSessionInitialize(NULL, NULL, InterruptionListener, this); if (err1 != noErr) { printf("Couldn't initialize audio session\n"); printError(err1); return OPEN_ERR; } err1 = AudioSessionSetActive(true); if (err1 != noErr) { printf("Couldn't set audio session active\n"); printError(err1); return OPEN_ERR; } UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; err1 = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); if (err1 != noErr) { printf("Couldn't set audio category\n"); printError(err1); return OPEN_ERR; } //err1 = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self), "couldn't set property listener"); Float64 hwSampleRate; outSize = sizeof(hwSampleRate); err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &outSize, &hwSampleRate); if (err1 != noErr) { printf("Couldn't get hw sample rate\n"); printError(err1); return OPEN_ERR; } else { printf("Get hw sample rate %f\n", hwSampleRate); } Float32 hwBufferSize; outSize = sizeof(hwBufferSize); err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &outSize, &hwBufferSize); if (err1 != noErr) { printf("Couldn't get hw buffer duration\n"); printError(err1); return OPEN_ERR; } else { printf("Get hw buffer duration %f\n", hwBufferSize); } UInt32 hwInput; outSize = sizeof(hwInput); err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &outSize, &hwInput); if (err1 != noErr) { printf("Couldn't get hw input channels\n"); printError(err1); return OPEN_ERR; } else { printf("Get hw input channels %d\n", hwInput); } UInt32 hwOutput; outSize = sizeof(hwOutput); err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &outSize, &hwOutput); if (err1 != noErr) { printf("Couldn't get hw output channels\n"); printError(err1); return OPEN_ERR; } else { printf("Get hw output channels %d\n", hwOutput); } Float32 preferredBufferSize = float(bufferSize) / float(samplerate); printf("preferredBufferSize %f \n", preferredBufferSize); err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize); if (err1 != noErr) { printf("Couldn't set i/o buffer duration\n"); printError(err1); return OPEN_ERR; } Float64 preferredSamplerate = float(samplerate); err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(preferredSamplerate), &preferredSamplerate); if (err1 != noErr) { printf("Couldn't set i/o sample rate\n"); printError(err1); return OPEN_ERR; } // AUHAL AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple, 0, 0}; AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd); err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL); if (err1 != noErr) { printf("Error calling OpenAComponent\n"); printError(err1); goto error; } enableIO = 1; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n"); printError(err1); goto error; } enableIO = 1; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n"); printError(err1); goto error; } UInt32 maxFPS; outSize = sizeof(maxFPS); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFPS, &outSize); if (err1 != noErr) { printf("Couldn't get kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } else { printf("Get kAudioUnitProperty_MaximumFramesPerSlice %d\n", maxFPS); } err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { printf("Cannot initialize AUHAL unit\n"); printError(err1); goto error; } // Setting format if (fDevNumInChans > 0) { outSize = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize); if (err1 != noErr) { printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } PrintStreamDesc(&srcFormat); srcFormat.mFormatID = kAudioFormatLinearPCM; srcFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; srcFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); srcFormat.mFramesPerPacket = 1; srcFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); srcFormat.mChannelsPerFrame = fDevNumInChans; srcFormat.mBitsPerChannel = 32; PrintStreamDesc(&srcFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } } if (fDevNumOutChans > 0) { outSize = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize); if (err1 != noErr) { printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); printError(err1); } PrintStreamDesc(&dstFormat); dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; dstFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); dstFormat.mFramesPerPacket = 1; dstFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); dstFormat.mChannelsPerFrame = fDevNumOutChans; dstFormat.mBitsPerChannel = 32; PrintStreamDesc(&dstFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); printError(err1); } } if (fDevNumInChans > 0 && fDevNumOutChans == 0) { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n"); printError(err1); goto error; } } else { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n"); printError(err1); goto error; } } return NO_ERR; error: AudioUnitUninitialize(fAUHAL); AudioComponentInstanceDispose(fAUHAL); return OPEN_ERR; } long TiPhoneCoreAudioRenderer::Close() { AudioUnitUninitialize(fAUHAL); AudioComponentInstanceDispose(fAUHAL); return NO_ERR; } long TiPhoneCoreAudioRenderer::Start() { AudioSessionSetActive(true); OSStatus err = AudioOutputUnitStart(fAUHAL); if (err != noErr) { printf("Error while opening device : device open error \n"); return OPEN_ERR; } else { return NO_ERR; } } long TiPhoneCoreAudioRenderer::Stop() { OSStatus err = AudioOutputUnitStop(fAUHAL); if (err != noErr) { printf("Error while closing device : device close error \n"); return OPEN_ERR; } else { return NO_ERR; } } /****************************************************************************** ******************************************************************************* MAIN PLAY THREAD ******************************************************************************* *******************************************************************************/ long lopt(char *argv[], const char *name, long def) { int i; for (i = 0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i + 1]); return def; } //------------------------------------------------------------------------- // MAIN //------------------------------------------------------------------------- int main(int argc, char *argv[]) { UI* interface = new CMDUI(argc, argv); TiPhoneCoreAudioRenderer audio_device(DSP.getNumInputs(), DSP.getNumOutputs()); long srate = (long)lopt(argv, "--frequency", 44100); int fpb = lopt(argv, "--buffer", 512); DSP.init(long(srate)); DSP.buildUserInterface(interface); if (audio_device.Open(fpb, srate) < 0) { printf("Cannot open CoreAudio device\n"); return 0; } if (audio_device.Start() < 0) { printf("Cannot start CoreAudio device\n"); return 0; } printf("inchan = %d, outchan = %d, freq = %ld\n", DSP.getNumInputs(), DSP.getNumOutputs(), srate); interface->run(); audio_device.Stop(); audio_device.Close(); return 0; } 1.9.12~dfsg/macosx/iphone/MainWindow.xib0000644000000000000000000004614113214314510016702 0ustar rootroot 528 10C540 740 1038.25 458.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin 62 YES YES com.apple.InterfaceBuilder.IBCocoaTouchPlugin YES YES YES YES IBFilesOwner IBFirstResponder 1316 YES 1316 {{25, 40}, {267, 21}} NO YES NO NetJack : client on JACK server Helvetica-Bold 17 16 1 MCAwIDAAA 1 10 {320, 480} 1 MSAxIDEAA NO NO YES delegate 4 window 5 YES 0 2 YES -1 File's Owner 3 -2 10 YES YES -1.CustomClassName -2.CustomClassName 10.IBPluginDependency 2.IBAttributePlaceholdersKey 2.IBEditorWindowLastContentRect 2.IBPluginDependency 2.IBUserGuides 3.CustomClassName 3.IBPluginDependency YES UIApplication UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin YES YES {{366, 320}, {320, 480}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin YES 153.5 0 iPhoneNetAppDelegate com.apple.InterfaceBuilder.IBCocoaTouchPlugin YES YES YES YES 11 YES iPhoneNetAppDelegate NSObject YES YES navigationController window YES UINavigationController UIWindow IBProjectSource iPhoneNetAppDelegate.h iPhoneNetAppDelegate NSObject IBUserSource YES NSObject IBFrameworkSource Foundation.framework/Headers/NSError.h NSObject IBFrameworkSource Foundation.framework/Headers/NSFileManager.h NSObject IBFrameworkSource Foundation.framework/Headers/NSKeyValueCoding.h NSObject IBFrameworkSource Foundation.framework/Headers/NSKeyValueObserving.h NSObject IBFrameworkSource Foundation.framework/Headers/NSKeyedArchiver.h NSObject IBFrameworkSource Foundation.framework/Headers/NSNetServices.h NSObject IBFrameworkSource Foundation.framework/Headers/NSObject.h NSObject IBFrameworkSource Foundation.framework/Headers/NSPort.h NSObject IBFrameworkSource Foundation.framework/Headers/NSRunLoop.h NSObject IBFrameworkSource Foundation.framework/Headers/NSStream.h NSObject IBFrameworkSource Foundation.framework/Headers/NSThread.h NSObject IBFrameworkSource Foundation.framework/Headers/NSURL.h NSObject IBFrameworkSource Foundation.framework/Headers/NSURLConnection.h NSObject IBFrameworkSource Foundation.framework/Headers/NSXMLParser.h NSObject IBFrameworkSource UIKit.framework/Headers/UINibLoading.h UIApplication UIResponder IBFrameworkSource UIKit.framework/Headers/UIApplication.h UILabel UIView IBFrameworkSource UIKit.framework/Headers/UILabel.h UINavigationController UIViewController IBFrameworkSource UIKit.framework/Headers/UINavigationController.h UIResponder NSObject IBFrameworkSource UIKit.framework/Headers/UIResponder.h UISearchBar UIView IBFrameworkSource UIKit.framework/Headers/UISearchBar.h UIView IBFrameworkSource UIKit.framework/Headers/UITextField.h UIView UIResponder IBFrameworkSource UIKit.framework/Headers/UIView.h UIViewController UIViewController IBFrameworkSource UIKit.framework/Headers/UITabBarController.h UIViewController UIResponder IBFrameworkSource UIKit.framework/Headers/UIViewController.h UIWindow UIView IBFrameworkSource UIKit.framework/Headers/UIWindow.h 0 com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 YES iPhoneNet.xcodeproj 3 3.1 1.9.12~dfsg/macosx/iphone/iPhoneNetAppDelegate.m0000644000000000000000000000120613214314510020256 0ustar rootroot// // iPhoneNetAppDelegate.m // iPhoneNet // // Created by Stéphane LETZ on 16/02/09. // Copyright Grame 2009. All rights reserved. // #import "iPhoneNetAppDelegate.h" @implementation iPhoneNetAppDelegate @synthesize window, navigationController; - (void)applicationDidFinishLaunching:(UIApplication *)application { // Override point for customization after application launch // add the navigation controller's view to the window [window addSubview: navigationController.view]; [window makeKeyAndVisible]; } - (void)dealloc { [navigationController release]; [window release]; [super dealloc]; } @end 1.9.12~dfsg/macosx/iphone/audio_thru.mm0000644000000000000000000000145013214314510016612 0ustar rootroot #include "JackAudioQueueAdapter.h" #define CHANNELS 2 static void DSPcompute(int count, float** input, float** output) { for (int i = 0; i < CHANNELS; i++) { memcpy(output[i], input[i], count * sizeof(float)); } } int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Jack::JackAudioQueueAdapter audio(2, 2, 512, 44100, DSPcompute); if (audio.Open() < 0) { fprintf(stderr, "Cannot open audio\n"); return 1; } // Hang around forever... while(1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false); int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; if (audio.Close() < 0) { fprintf(stderr, "Cannot close audio\n"); } return retVal; } 1.9.12~dfsg/macosx/iphone/icon.png0000644000000000000000000001226113214314510015554 0ustar rootroot‰PNG  IHDR00Wù‡îiCCPICC Profilex…TÏkAþ6n©Ð"Zk²x"IY«hEÔ6ýbk Û¶Ed3IÖn6ëî&µ¥ˆäâÑ*ÞEí¡ÿ€zðd/J…ZE(Þ«(b¡-ñÍnL¶¥êÀÎ~óÞ7ï}ovß rÒ4õ€ä ÇR¢il|BjüˆŽ¢ A4%UÛìN$Aƒsù{çØz[VÃ{ûw²w­šÒ¶š„ý@àGšÙ*°ïq Yˆ<ß¡)ÇtßãØòì9NyxÁµ+=ÄY"|@5-ÎM¸SÍ%Ó@ƒH8”õqR>œ×‹”×infÆÈ½O¦»Ìî«b¡œNö½ô~N³Þ>Â! ­?F¸žõŒÕ?âaá¤æÄ†=5ôø`·©ø5Â_M'¢TqÙ. ñ˜®ýVòJ‚p8Êda€sZHO×Lnøº‡}&ׯâwVQáygÞÔÝïEÚ¯0  š HPEa˜°P@†<14²r?#«“{2u$j»tbD±A{6Ü=·Q¤Ý<þ("q”Cµ’üAþ*¯ÉOåyùË\°ØV÷”­›šºòà;Å噹×ÓÈãsM^|•Ôv“WG–¬yz¼šì?ìW—1æ‚5Äs°ûñ-_•Ì—)ŒÅãUóêK„uZ17ߟl;=â.Ï.µÖs­‰‹7V›—gýjHû“æUùO^õñügÍÄcâ)1&vŠç!‰—Å.ñ’ØK« â`mÇ•†)Òm‘ú$Õ``š¼õ/]?[x½F õQ”ÌÒT‰÷Â*d4¹oúÛÇüä÷ŠçŸ(/làÈ™ºmSqï¡e¥ns®¿Ñ}ð¶nk£~8üX<«­R5Ÿ ¼v‡zè)˜Ó––Í9R‡,Ÿ“ºéÊbRÌPÛCRR×%×eK³™UbévØ™Ón¡9B÷ħJe“ú¯ñ°ý°Rùù¬RÙ~NÖ—úoÀ¼ýEÀx‹‰ pHYs  šœiIDAThÕY tTU¶Ýo¨÷j®¤¨$•!B˜$AÅQA´ëÓb£Ò[@ìeÛ*‡Våcc£"Ò ‚ÚòÑ(* *%  !@HÈP•¤æñÕ«÷Ï VBè4Ëå¿+ɽïŽçÜ{ÎÞçÞ—!ùÜî)÷Ü0B)--Õ\†é.j ö¢zŸ§s0ùæþ9 â¬{ç<]~ýÕ•¥{”ÙwMPœ ·þ’Ò^–Pæ ºµwM¿‡ö|ûñÿKSÊ+†ÁK‹—²ÅÅÅâ/¥Äe;œœœ2ÁàŸpËŒZôÜ/¥Àe]§l×®IJ,¦,üãJkkëÀË1ù–M~9wÖÅÓX?¯³ù.Û ¨“¾i×—ŸÆN×ÕaÇÇë·ÖTìÿÃååWCÁ%¯#rlêð¡ƒàs»†u¦ßYå¿S—?ðÊÕco¼ö¾×W®O“–¯^mLIÅ?6ã_¼”y¥°$(4¸&½³ñ—U¥Ï>³[f¸¡µ'ªŽÅ“YX V¾ñÆ ´ø%)  &‚åð83;Sà’¶³ÉŽæô÷ÀaÃѯoâJ>²öÏ>{µ³1ÿWFÐJˆÇ!Å™N»^V&Ý=eNmÍiü~]9˜Öå!…$€añêËKR¥s):­ñÔ‰G3äHˆ¯¯9‚Æê£ù¯¿øÂúúú´öÝ/Xuqç±cj?¸cyÈÈ‘›²{t•+**aÐi‘f³ $Eàlv!ªÄ°~õê:Ž9ß÷¢'þ²8##Ã9pÔ5b¼M•ÇÁ#rEIñ&Gû1¬@UEÅ ˆÂ‹¬XVÞ~‚ŽåI“&í©:V —׋±cÆP3Y1ùC< lX·¾ˆ6ÂÔqLgßÁ  ÁqIé«õp…CH1›޶Õ'‡\°ùýû¯,?p ¶ãË­v}¾yNr†…‘cn¸³¹¹UUÇ‘nC,JÂÇI AŠHØðîº{; 9çsÁ‚ü©Ó5`†ˆs ^uíq„ƒ>ÈQ2Évé‚PÇ\?áVͫ—½¶Äív÷l7O²h³ÙNççöÄ‘ÊjÔ՟ƈ«‡ƒeðŒA+â྽&;Ÿ§0sÆïþ(ŠÚ¶V–eer!¸dQÚ})@͉ê$©]°S%Öú±´t…ôþþ•«¢×Ü$’m /**RÇ^’rNÞÛð9ÁÄÂ`³r€.ià¬zXõ"z:è$¾_»áu›'OzM‡ÑÔÔˆ}û‘ýr`ù8B„é_mþt†Ú§}bx~¯ÕC ~Õè$X:C"Õi´ò –­jZ‚:î’ÇßñæÚ[¾”jOÄ´L÷^àìYÐv·Ánq£C¤©oÝ:™,Q–¯y»a0¬¨ÌÉNñPЧŸoÜωPÉy·ªÔ-ód>¤f›~Dh”“*,µÑxƒÅB‹ÓcB[«ÚDÁšºØú§79ÃÙ^_Ú˜úº²‘LÌ“Ö*çŠV%…xÁ̤JoÊÓwö‰j¹Øb˜˜D^×(º„ü0eDЃìœõåuØþÔóÕiÙÙ¬©ºp—4ë¶òoŽŽÏÈHÏsެ¬¬šÄú‰Ül6nihEá ú]AÖ£:¬‚…±0!'@¢ØŠ¿N“T@~Üceʪb'¬ì•Y=#þ*$ÂàuÏ“‘!<Á€N°ÑLˆø|µzsot͉?hÞ„ÍsÁ0œ(Ƕ­y®ßÞQ´âÃ:uÁgjÿçŸ}5ÈÝêë¹sû7SGŒµN­oŸx–ý†ä-˜ŒˆË$‚ý¡6ô’Iø+†=Ÿè– ù ¼ä`Œ"C¢ŠC!E•"œHÆÃ É„L0(òQ„JãÔF)¨C¨é0ù†aù’סµÚÐ…¡ø%ìÇ‘•«×$¼Îìqi6"‡g>ó^¢¾}nÉȸžB¶ûºOø<^x=nx^(<‹ôœì’œy'ú'¨jQºÊWLœm;µ8Ý= p $ÛèYRÈ€Þ¸ ^ΑuÚåmð¦POöÒÅq;Œ&4[Ià¥÷àÅÉCqbêèÆ‹ˆ:Úƒž)©‹¦§§7Ìš;k±ÛíƒHqÑÆµëÚˆ/!P"OMM]a¶ÙjÏDz†d!%tëÿa¢š'p5zúPU rˆìBf eðI)ät,R˜…³Zù‚´,˜ÝTl ‹Š}wá¤ã~Š4òn€Ð6Žc[]-þç“Mðgg±Z“ñÒãÆ=jMÑHX¼èå$ñµL-;káÀ·_bÞƒ@¤ë)¯!¹Xöýöý’ ¯ô¥‹'” ™DŒh#ÆBk„Œ(R˜xUŽ\p„ÏÑp9íìPRFB*ók‘r-¹CN&™š  x>Î W™ÛÄ­˜¿üAå?[•À'>é¹]ŠòÛ¹[ö–lÑ#`!JJKßu+J^©¢œõºÞµ¼ KW¼E>(‹«¼F„Ð.%øD“?d÷ôC> ‘Sî@Z6tôÖK½‘mŒ:íRò|l1lái®ò¯D±¿†îÂÑà…!ˆxC¶eÁsêG0{ôŸd¦>®Ûú$qG*úÌ»Üà[ðOÓ Ór48B3ôMÈç!(v»\(Ù¹ ½óº!Jþg±X"‰v5Ož@3’ 0Æ<`ü…¬ôКEDR€aщhB¡ZIÀd*Ý¡¸2ˆÿ¶(±qˆ°3ªƒÑ/¥?\mgÎAÔɃí>J&Íÿ ,§k¦½/”œqtÝ$£%T“I,‡Œ³v×’Ù ¹}¯ÀÄ»ïšFÊÁãñ´¡YB‰¤'낹ˆ ʋɉôÿå®îˆ3A6d¢5JŒÛÆ),\%4ŠH ºàeÆB²Ýäüj EÎ÷Ÿ ‡: óá5ó2„‚«Vw¡SUN|¿ `ôôdG(¦&9ŒŠcÅ™¯3ƒîV4Y>¸ ]lÔ˜ˆ­ý’&äl§Iñ,ÌÄ”¿bïñ[gÂsâr%86_ IÚ’›ì¬DèNŽUJ[G&•3\ý (–^dz~èµD¹lÂpò#G)Á,ÝKÐÚä‚8c#â^™"K–”¥_š“Š …µù¤1!˜šóFó*«ÉbµÆqMŽúj#+Ú»wïñö}~Òè3i«S+ð¶h+8ù‰–¼Y!i‹Ž.æ6Å0" Cô.Òyë>uAr*dÂâ¾ œpܽFNå\´„Ÿ?*)»gãŸûuB^w ¡yëèfEî¦pàÈá‰Bhþ3'ppÜõØòÝö¤Lª [‹‹Ç?4{þ§Ç+ΪO(‘<&BD‘ž†„–ÈVŠ•¢1ƒÆQx¢ „Éi‰Y=ªÐ>% ($Ç}¨|‹åßo†Žq!kÿhÒÌ‚8ØŽx¤ ñ`\ß(ÂK°-ûu10vN›à EêI¨žÈJÄótkS³ìv{SBÀêµ×x}¡Äç9yRV>c †|@V¼0PëýG8íÖ¶Ý)âzÞB©À´Z‰\lã­7âÍñÅh‰Z±/\€m¡1R¤ xyš½„V…&H=n‚XrüûºC;è6òr{âŽ8'î ÐÝׄÍï°…¤,LHêv:IB¸ó¤¤ãA&zGu€ˆŒöšÌ–z^EG7)•]ñ8˜¬ ÒÍ<휀@‹„Hýw 1x(z4 š„!ö0n &Ûc•†ï¯{ö´(ù üÐÜ=ìº7 EDØ…ø†æ%·dÉÿš›ñÕï"¥¬ µª2;Ý^CT:‘v¦CR™vAãâ²ØÉÎýdNåˆ÷`ÁÚføé-¦€ Ï¢.DèO†+KzL’BÐ'@O'c¤{nhßûð¸8I/Ò©ýGbb6ƒ©"Ì2ÝÄ‚›ñ$7!‚yqæß‹„ÔäggÀ¢Oxé¥k×L,ýë"" ´]ˆšê›2Ô¹Bg½(&uI* ÐSEŒ'ø£`NÜ´;f°ýÌ0µ0¨'ë=Mõ™q+ Þ8ÉC„B ²á %";…¾BeÛQ_ú!Q©Ä¨ùöÌõ~„C¶B¸õéøJxi´ºòŽÍÆÖ̬.V“I‡ÍH(À±ÜO·ù¤Ìg’ °„g¼–`&” Ùĸ=é-g01‹• ’Þçér¦°VCˆ$h¼Ð¥ø°Û;·7ŸdKs}íãocà@kM§xÔ=…–ÈQŒ¤©z:jéZ(cpt1ö 9ˆ*ÚÝú— %¨mÈ0¥YkëëUÂ2ÓW˜2eJ4ÓžæFBgIÝî#©@ùçcÓFOÿº®®i÷øk3>?:g½ÚoW»Îí‹êèû}e3w~-Ïü*çrÓqå[>ÔTEQ¦ º"·{*)Fq|VíQ¼¾e'…[fDUΦ ‘ß>Fѳ/nÉ&åöi“·?ý_ÏîÕ½®6âZïoi™öj“Î8ªÅÛ~õŸËbëÏÍ^ª¬TÒ‚AoêÁý©¾VÇÐPì`aØ·7‹í£u!ûTA ácµ„z´L'r´/Œ= ˜Ñ%i˜ìqÞqï]ÓvÛsì¤x†÷å7–Y¾Û±c̼‡þ´eþˆê‰t”(y.ö;?Ÿð•@ƒ~¶[U¾§DwhòG+Ó£ö|+«…Å*ó‘8*¹ýàØ‘òÌcQÿ~K3ô4¿¯ÎiVç1jÔn½ Çžõgú CFBundleDevelopmentRegion English CFBundleDisplayName ${PRODUCT_NAME} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier fr.grame.iGrame.iPhoneFaustNet CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleSignature ???? CFBundleVersion 1.0 LSRequiresIPhoneOS NSMainNibFile MainWindow 1.9.12~dfsg/macosx/iphone/iPhoneNetAppDelegate.h0000644000000000000000000000104413214314510020251 0ustar rootroot// // iPhoneNetAppDelegate.h // iPhoneNet // // Created by Stéphane LETZ on 16/02/09. // Copyright Grame 2009. All rights reserved. // #import @interface iPhoneNetAppDelegate : NSObject { // UIWindow *window; IBOutlet UIWindow *window; IBOutlet UINavigationController *navigationController; } //@property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) UIWindow *window; @property (nonatomic, retain) UINavigationController *navigationController; @end 1.9.12~dfsg/macosx/iphone/main_master.mm0000644000000000000000000001064313214314510016752 0ustar rootroot// // main.m // iPhoneNet // // Created by Stéphane LETZ on 16/02/09. // Copyright Grame 2009. All rights reserved. // #import #include #include "TiPhoneCoreAudioRenderer.h" #define NUM_INPUT 2 #define NUM_OUTPUT 2 jack_net_master_t* net; jack_adapter_t* adapter; float** audio_input_buffer = NULL; float** audio_output_buffer = NULL; int buffer_size = 1024; int sample_rate = 22050; //int sample_rate = 32000; jack_master_t request = { -1, -1, -1, -1, buffer_size, sample_rate, "master" }; jack_slave_t result; static void MixAudio(float** dst, float** src1, float** src2, int channels, int buffer_size) { for (int chan = 0; chan < channels; chan++) { for (int frame = 0; frame < buffer_size; frame++) { dst[chan][frame] = src1[chan][frame] + src2[chan][frame]; } } } static void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) { int i; // Copy from iPod input to network buffers for (i = 0; i < result.audio_input; i++) { memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float)); } /* // Copy from network out buffers to network in buffers (audio thru) for (i = 0; i < result.audio_input; i++) { memcpy(audio_input_buffer[i], audio_output_buffer[i], buffer_size * sizeof(float)); } */ // Mix iPod input and network in buffers to network out buffers //MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size); // Send network buffers if (jack_net_master_send(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { printf("jack_net_master_send error..\n"); } // Recv network buffers if (jack_net_master_recv(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { printf("jack_net_master_recv error..\n"); } // Copy from network buffers to iPod output for (i = 0; i < result.audio_output; i++) { memcpy(outputs[i], audio_output_buffer[i], buffer_size * sizeof(float)); } } int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int i; if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { printf("jack_net_master_open error..\n"); return -1; } TiPhoneCoreAudioRenderer audio_device(result.audio_input, result.audio_output); // Allocate buffers if (result.audio_input > 0) { audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*)); for (i = 0; i < result.audio_input; i++) { audio_input_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); } } if (result.audio_output > 0) { audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*)); for (i = 0; i < result.audio_output; i++) { audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); } } if (audio_device.Open(buffer_size, sample_rate) < 0) { return -1; } audio_device.SetAudioCallback(MasterAudioCallback, NULL); if (audio_device.Start() < 0) { return -1; } /* // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... // Run until interrupted int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); while (1) { // Copy input to output for (i = 0; i < result.audio_input; i++) { memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); } if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { printf("jack_net_master_send error..\n"); } if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { printf("jack_net_master_recv error..\n"); } usleep(wait_usec); }; */ int retVal = UIApplicationMain(argc, argv, nil, nil); audio_device.Stop(); audio_device.Close(); // Wait for application end jack_net_master_close(net); for (i = 0; i < result.audio_input; i++) { free(audio_input_buffer[i]); } free(audio_input_buffer); for (i = 0; i < result.audio_output; i++) { free(audio_output_buffer[i]); } free(audio_output_buffer); [pool release]; return retVal; } 1.9.12~dfsg/macosx/iphone/iPhoneNet.xcodeproj/0000755000000000000000000000000013214314510020001 5ustar rootroot1.9.12~dfsg/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj0000755000000000000000000020607013214314510023065 0ustar rootroot// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4B0772210F54018C000DC657 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4B0772240F54018C000DC657 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4B0772250F54018C000DC657 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; 4B0772260F54018C000DC657 /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; 4B0772270F54018C000DC657 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; 4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; 4B0772310F54018C000DC657 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 4B0772320F54018C000DC657 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4B0772330F54018C000DC657 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4B0772340F54018C000DC657 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4B07724A0F54021B000DC657 /* main_slave.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772490F54021B000DC657 /* main_slave.mm */; }; 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; 4B0773880F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; 4B1A94140F49BE2C00D3626B /* iPhoneNet_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */; }; 4B1A94150F49BE2F00D3626B /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4B1A94160F49BE3000D3626B /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1A93540F49ACFC00D3626B /* JackMachThread.h */; }; 4B1A94170F49BE3100D3626B /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; 4B1A94180F49BE3100D3626B /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; 4B1A94190F49BE3300D3626B /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; 4B1A941A0F49BE3300D3626B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4B1A941B0F49BE3400D3626B /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4B1A941C0F49BE3500D3626B /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1A93520F49ACF300D3626B /* JackNetUnixSocket.h */; }; 4B1A941D0F49BE3500D3626B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4B1A941E0F49BE3600D3626B /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1A933C0F49AC4500D3626B /* JackPosixThread.h */; }; 4B1A94540F49C03300D3626B /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4B1A94550F49C03300D3626B /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; 4B1A94560F49C03400D3626B /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; 4B1A94570F49C03500D3626B /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; 4B1A94580F49C03600D3626B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4B1A94590F49C03600D3626B /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4B1A945A0F49C03600D3626B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4B1A95760F49CEAB00D3626B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B41469810BD3C4300C12F0C /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4B41469A10BD3C4300C12F0C /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4B41469B10BD3C4300C12F0C /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; 4B41469C10BD3C4300C12F0C /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; 4B41469D10BD3C4300C12F0C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; 4B41469E10BD3C4300C12F0C /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4B41469F10BD3C4300C12F0C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4B4146A010BD3C4300C12F0C /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4B4146A210BD3C4300C12F0C /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4B4146A310BD3C4300C12F0C /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4B4146A410BD3C4300C12F0C /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; 4B4146A510BD3C4300C12F0C /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B4146A910BD3C4300C12F0C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 4B4146AA10BD3C4300C12F0C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4B6B712C114BAE9A00ED9788 /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4B9CB1371136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4B9CB1381136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4B9CB1391136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4B9CB13A1136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4B9CB13B1136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4B9CB13C1136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; 4BC9C1F71135AB2800D22670 /* main_master.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772500F54022D000DC657 /* main_master.mm */; }; 4BCB37B6112D647C008C7BC1 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BCB37C7112D647C008C7BC1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 4BCB37C8112D647C008C7BC1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4BCB37C9112D647C008C7BC1 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4BCB37CA112D647C008C7BC1 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */; }; 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BCF75DC10BC2FD90082C526 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4BCF75DD10BC2FD90082C526 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; 4BCF75DE10BC2FD90082C526 /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; 4BCF75DF10BC2FD90082C526 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; 4BCF75E010BC2FD90082C526 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4BCF75E110BC2FD90082C526 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4BCF75E210BC2FD90082C526 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4BCF75E410BC2FD90082C526 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BCF75E510BC2FD90082C526 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4BCF75E610BC2FD90082C526 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; 4BCF75E710BC2FD90082C526 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4BCF75EB10BC2FD90082C526 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 4BCF75EC10BC2FD90082C526 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4BCF75ED10BC2FD90082C526 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4BCF75EE10BC2FD90082C526 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF75F610BC30140082C526 /* audio_thru.mm */; }; 4BDFCD3D113DB6B700D77992 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BDFCD3E113DB6B700D77992 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4BDFCD4A113DB6B700D77992 /* main_slave.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772490F54021B000DC657 /* main_slave.mm */; }; 4BDFCD4B113DB6B700D77992 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; 4BDFCD4D113DB6B700D77992 /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BDFCD4E113DB6B700D77992 /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; 4BDFCD50113DB6B700D77992 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 4BDFCD51113DB6B700D77992 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4BDFCD52113DB6B700D77992 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4BDFCD53113DB6B700D77992 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136130F4B0B5E00218A3F /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */; }; 4BF1364D0F4B0F7700218A3F /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4BF1364E0F4B0F7700218A3F /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4BF1364F0F4B0F7700218A3F /* JackResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF1364C0F4B0F7700218A3F /* JackResampler.h */; }; 4BF136550F4B0F9F00218A3F /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; 4BF136560F4B0F9F00218A3F /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; 4BF15E2511356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2611356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2711356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15F7811357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; 4BF15F7911357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; 4BF15F7A11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; 4BF15F7B11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; 4BF15F7C11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; 4BF15F7D11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; 4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BFF45630F4D5D9700106083 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4BFF45640F4D5D9700106083 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; 4BFF45650F4D5D9700106083 /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; 4BFF45660F4D5D9700106083 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; 4BFF45670F4D5D9700106083 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4BFF45680F4D5D9700106083 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4BFF45690F4D5D9700106083 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4BFF456B0F4D5D9700106083 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BFF456C0F4D5D9700106083 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4BFF456D0F4D5D9700106083 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; 4BFF45700F4D5D9700106083 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 4BFF45710F4D5D9700106083 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4BFF45720F4D5D9700106083 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4BFF45730F4D5D9700106083 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneNet_Prefix.pch; sourceTree = ""; }; 4B0772380F54018C000DC657 /* NetJackMaster.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackMaster.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4B0772490F54021B000DC657 /* main_slave.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main_slave.mm; sourceTree = SOURCE_ROOT; }; 4B0772500F54022D000DC657 /* main_master.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main_master.mm; sourceTree = SOURCE_ROOT; }; 4B0773840F541EE2000DC657 /* iPhoneNetAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneNetAppDelegate.h; sourceTree = ""; }; 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iPhoneNetAppDelegate.m; sourceTree = ""; }; 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetAPI.cpp; path = ../../common/JackNetAPI.cpp; sourceTree = SOURCE_ROOT; }; 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetInterface.cpp; path = ../../common/JackNetInterface.cpp; sourceTree = SOURCE_ROOT; }; 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetTool.cpp; path = ../../common/JackNetTool.cpp; sourceTree = SOURCE_ROOT; }; 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPosixThread.cpp; path = ../../posix/JackPosixThread.cpp; sourceTree = SOURCE_ROOT; }; 4B1A933C0F49AC4500D3626B /* JackPosixThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPosixThread.h; path = ../../posix/JackPosixThread.h; sourceTree = SOURCE_ROOT; }; 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetUnixSocket.cpp; path = ../../posix/JackNetUnixSocket.cpp; sourceTree = SOURCE_ROOT; }; 4B1A93520F49ACF300D3626B /* JackNetUnixSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetUnixSocket.h; path = ../../posix/JackNetUnixSocket.h; sourceTree = SOURCE_ROOT; }; 4B1A93540F49ACFC00D3626B /* JackMachThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMachThread.h; path = ../JackMachThread.h; sourceTree = SOURCE_ROOT; }; 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMachThread.cpp; path = ../JackMachThread.cpp; sourceTree = SOURCE_ROOT; }; 4B1A93870F49B0E300D3626B /* JackMachTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = JackMachTime.c; path = ../JackMachTime.c; sourceTree = SOURCE_ROOT; }; 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4B9CB1361136CA99007DE01A /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = SOURCE_ROOT; }; 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iPhoneNetMasterAppl-Info.plist"; sourceTree = ""; }; 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; 4BF1364C0F4B0F7700218A3F /* JackResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackResampler.h; path = ../../common/JackResampler.h; sourceTree = SOURCE_ROOT; }; 4BF136540F4B0F9F00218A3F /* ringbuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ringbuffer.c; path = ../../common/ringbuffer.c; sourceTree = SOURCE_ROOT; }; 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAHostTimeBase.cpp; path = /Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.cpp; sourceTree = ""; }; 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TiPhoneCoreAudioRenderer.cpp; path = ../coreaudio/TiPhoneCoreAudioRenderer.cpp; sourceTree = SOURCE_ROOT; }; 4BFF45120F4D59DB00106083 /* libjacknet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjacknet.a; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, 4B1A95760F49CEAB00D3626B /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B0772300F54018C000DC657 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4B0772310F54018C000DC657 /* Foundation.framework in Frameworks */, 4B0772320F54018C000DC657 /* UIKit.framework in Frameworks */, 4B0772330F54018C000DC657 /* CoreGraphics.framework in Frameworks */, 4B0772340F54018C000DC657 /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B1A940E0F49BDE000D3626B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 4B4146A810BD3C4300C12F0C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4B4146A910BD3C4300C12F0C /* Foundation.framework in Frameworks */, 4B4146AA10BD3C4300C12F0C /* UIKit.framework in Frameworks */, 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */, 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BCB37C6112D647C008C7BC1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BCB37C7112D647C008C7BC1 /* Foundation.framework in Frameworks */, 4BCB37C8112D647C008C7BC1 /* UIKit.framework in Frameworks */, 4BCB37C9112D647C008C7BC1 /* CoreGraphics.framework in Frameworks */, 4BCB37CA112D647C008C7BC1 /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BCF75EA10BC2FD90082C526 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BCF75EB10BC2FD90082C526 /* Foundation.framework in Frameworks */, 4BCF75EC10BC2FD90082C526 /* UIKit.framework in Frameworks */, 4BCF75ED10BC2FD90082C526 /* CoreGraphics.framework in Frameworks */, 4BCF75EE10BC2FD90082C526 /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDFCD4F113DB6B700D77992 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BDFCD50113DB6B700D77992 /* Foundation.framework in Frameworks */, 4BDFCD51113DB6B700D77992 /* UIKit.framework in Frameworks */, 4BDFCD52113DB6B700D77992 /* CoreGraphics.framework in Frameworks */, 4BDFCD53113DB6B700D77992 /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFF456F0F4D5D9700106083 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4BFF45700F4D5D9700106083 /* Foundation.framework in Frameworks */, 4BFF45710F4D5D9700106083 /* UIKit.framework in Frameworks */, 4BFF45720F4D5D9700106083 /* CoreGraphics.framework in Frameworks */, 4BFF45730F4D5D9700106083 /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */, 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* NetJackMaster.app */, 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */, ); name = Products; sourceTree = ""; }; 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */, 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */, 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, ); name = CustomTemplate; sourceTree = ""; }; 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( 29B97317FDCFA39411CA2CEA /* Resources */, 4BCF75F610BC30140082C526 /* audio_thru.mm */, 4BBDC8F90F5420C000465F9C /* freeverb.mm */, 4B0773840F541EE2000DC657 /* iPhoneNetAppDelegate.h */, 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */, 4BF136540F4B0F9F00218A3F /* ringbuffer.c */, 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */, 4BF1364C0F4B0F7700218A3F /* JackResampler.h */, 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */, 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */, 4B1A93870F49B0E300D3626B /* JackMachTime.c */, 4B1A93540F49ACFC00D3626B /* JackMachThread.h */, 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */, 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */, 4B1A93520F49ACF300D3626B /* JackNetUnixSocket.h */, 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */, 4B1A933C0F49AC4500D3626B /* JackPosixThread.h */, 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */, 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */, 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */, 4B2791870F72570C000536B7 /* JackGlobals.cpp */, 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */, 4B0772490F54021B000DC657 /* main_slave.mm */, 4B0772500F54022D000DC657 /* main_master.mm */, ); name = "Other Sources"; sourceTree = ""; }; 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( 4B9CB1361136CA99007DE01A /* icon.png */, 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 8D1107310486CEB800E47090 /* Info.plist */, 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */, ); name = Resources; sourceTree = ""; }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */, 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 1D30AB110D05D00D00671497 /* Foundation.framework */, 288765FC0DF74451002DB57D /* CoreGraphics.framework */, ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 4B1A940C0F49BDE000D3626B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4B1A94140F49BE2C00D3626B /* iPhoneNet_Prefix.pch in Headers */, 4B1A94160F49BE3000D3626B /* JackMachThread.h in Headers */, 4B1A941C0F49BE3500D3626B /* JackNetUnixSocket.h in Headers */, 4B1A941E0F49BE3600D3626B /* JackPosixThread.h in Headers */, 4BF136130F4B0B5E00218A3F /* JackAudioAdapterInterface.h in Headers */, 4BF1364F0F4B0F7700218A3F /* JackResampler.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 1D6058900D05DD3D006BFB54 /* iPhoneNetSlave */ = { isa = PBXNativeTarget; buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "iPhoneNetSlave" */; buildPhases = ( 1D60588D0D05DD3D006BFB54 /* Resources */, 1D60588E0D05DD3D006BFB54 /* Sources */, 1D60588F0D05DD3D006BFB54 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = iPhoneNetSlave; productName = iPhoneNet; productReference = 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */; productType = "com.apple.product-type.application"; }; 4B07721F0F54018C000DC657 /* iPhoneNetMaster */ = { isa = PBXNativeTarget; buildConfigurationList = 4B0772350F54018C000DC657 /* Build configuration list for PBXNativeTarget "iPhoneNetMaster" */; buildPhases = ( 4B0772200F54018C000DC657 /* Resources */, 4B0772220F54018C000DC657 /* Sources */, 4B0772300F54018C000DC657 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = iPhoneNetMaster; productName = iPhoneNet; productReference = 4B0772380F54018C000DC657 /* NetJackMaster.app */; productType = "com.apple.product-type.application"; }; 4B1A940F0F49BDE000D3626B /* libjacknet */ = { isa = PBXNativeTarget; buildConfigurationList = 4B1A94130F49BDFF00D3626B /* Build configuration list for PBXNativeTarget "libjacknet" */; buildPhases = ( 4B1A940C0F49BDE000D3626B /* Headers */, 4B1A940D0F49BDE000D3626B /* Sources */, 4B1A940E0F49BDE000D3626B /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = libjacknet; productName = jacknet; productReference = 4BFF45120F4D59DB00106083 /* libjacknet.a */; productType = "com.apple.product-type.library.static"; }; 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */ = { isa = PBXNativeTarget; buildConfigurationList = 4B4146AD10BD3C4300C12F0C /* Build configuration list for PBXNativeTarget "iPhoneFaustNet Distribution" */; buildPhases = ( 4B41469710BD3C4300C12F0C /* Resources */, 4B41469910BD3C4300C12F0C /* Sources */, 4B4146A810BD3C4300C12F0C /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "iPhoneFaustNet Distribution"; productName = iPhoneNet; productReference = 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */; productType = "com.apple.product-type.application"; }; 4BCB37B4112D647C008C7BC1 /* iPhoneFaust */ = { isa = PBXNativeTarget; buildConfigurationList = 4BCB37CB112D647C008C7BC1 /* Build configuration list for PBXNativeTarget "iPhoneFaust" */; buildPhases = ( 4BCB37B5112D647C008C7BC1 /* Resources */, 4BCB37B7112D647C008C7BC1 /* Sources */, 4BCB37C6112D647C008C7BC1 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = iPhoneFaust; productName = iPhoneNet; productReference = 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */; productType = "com.apple.product-type.application"; }; 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */ = { isa = PBXNativeTarget; buildConfigurationList = 4BCF75EF10BC2FD90082C526 /* Build configuration list for PBXNativeTarget "iPhoneThruNet" */; buildPhases = ( 4BCF75D910BC2FD90082C526 /* Resources */, 4BCF75DB10BC2FD90082C526 /* Sources */, 4BCF75EA10BC2FD90082C526 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = iPhoneThruNet; productName = iPhoneNet; productReference = 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */; productType = "com.apple.product-type.application"; }; 4BDFCD3B113DB6B700D77992 /* iPhoneNetSlaveLib */ = { isa = PBXNativeTarget; buildConfigurationList = 4BDFCD54113DB6B700D77992 /* Build configuration list for PBXNativeTarget "iPhoneNetSlaveLib" */; buildPhases = ( 4BDFCD3C113DB6B700D77992 /* Resources */, 4BDFCD3F113DB6B700D77992 /* Sources */, 4BDFCD4F113DB6B700D77992 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = iPhoneNetSlaveLib; productName = iPhoneNet; productReference = 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */; productType = "com.apple.product-type.application"; }; 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */; buildPhases = ( 4BFF455F0F4D5D9700106083 /* Resources */, 4BFF45610F4D5D9700106083 /* Sources */, 4BFF456F0F4D5D9700106083 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = iPhoneFaustNet; productName = iPhoneNet; productReference = 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneNet" */; compatibilityVersion = "Xcode 3.1"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectRoot = ""; targets = ( 4B07721F0F54018C000DC657 /* iPhoneNetMaster */, 1D6058900D05DD3D006BFB54 /* iPhoneNetSlave */, 4BDFCD3B113DB6B700D77992 /* iPhoneNetSlaveLib */, 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */, 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */, 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */, 4BCB37B4112D647C008C7BC1 /* iPhoneFaust */, 4B1A940F0F49BDE000D3626B /* libjacknet */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 1D60588D0D05DD3D006BFB54 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, 4B9CB1381136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B0772200F54018C000DC657 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B0772210F54018C000DC657 /* MainWindow.xib in Resources */, 4B9CB1371136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B41469710BD3C4300C12F0C /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B41469810BD3C4300C12F0C /* MainWindow.xib in Resources */, 4B9CB13B1136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BCB37B5112D647C008C7BC1 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BCB37B6112D647C008C7BC1 /* MainWindow.xib in Resources */, 4B9CB13C1136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BCF75D910BC2FD90082C526 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */, 4B9CB13A1136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDFCD3C113DB6B700D77992 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BDFCD3D113DB6B700D77992 /* MainWindow.xib in Resources */, 4BDFCD3E113DB6B700D77992 /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFF455F0F4D5D9700106083 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */, 4B9CB1391136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 1D60588E0D05DD3D006BFB54 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B1A94540F49C03300D3626B /* JackMachThread.cpp in Sources */, 4B1A94550F49C03300D3626B /* JackMachTime.c in Sources */, 4B1A94560F49C03400D3626B /* JackNetAPI.cpp in Sources */, 4B1A94570F49C03500D3626B /* JackNetInterface.cpp in Sources */, 4B1A94580F49C03600D3626B /* JackNetTool.cpp in Sources */, 4B1A94590F49C03600D3626B /* JackNetUnixSocket.cpp in Sources */, 4B1A945A0F49C03600D3626B /* JackPosixThread.cpp in Sources */, 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */, 4BF1364D0F4B0F7700218A3F /* JackResampler.cpp in Sources */, 4BF136550F4B0F9F00218A3F /* ringbuffer.c in Sources */, 4B07724A0F54021B000DC657 /* main_slave.mm in Sources */, 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */, 4BF15E2611356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15F7911357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B0772220F54018C000DC657 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B0772240F54018C000DC657 /* JackMachThread.cpp in Sources */, 4B0772250F54018C000DC657 /* JackMachTime.c in Sources */, 4B0772260F54018C000DC657 /* JackNetAPI.cpp in Sources */, 4B0772270F54018C000DC657 /* JackNetInterface.cpp in Sources */, 4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */, 4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */, 4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */, 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */, 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */, 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */, 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */, 4BF15E2511356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15F7811357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, 4BC9C1F71135AB2800D22670 /* main_master.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B1A940D0F49BDE000D3626B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B1A94150F49BE2F00D3626B /* JackMachThread.cpp in Sources */, 4B1A94170F49BE3100D3626B /* JackMachTime.c in Sources */, 4B1A94180F49BE3100D3626B /* JackNetAPI.cpp in Sources */, 4B1A94190F49BE3300D3626B /* JackNetInterface.cpp in Sources */, 4B1A941A0F49BE3300D3626B /* JackNetTool.cpp in Sources */, 4B1A941B0F49BE3400D3626B /* JackNetUnixSocket.cpp in Sources */, 4B1A941D0F49BE3500D3626B /* JackPosixThread.cpp in Sources */, 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */, 4BF1364E0F4B0F7700218A3F /* JackResampler.cpp in Sources */, 4BF136560F4B0F9F00218A3F /* ringbuffer.c in Sources */, 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */, 4B6B712C114BAE9A00ED9788 /* CAHostTimeBase.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B41469910BD3C4300C12F0C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B41469A10BD3C4300C12F0C /* JackMachThread.cpp in Sources */, 4B41469B10BD3C4300C12F0C /* JackMachTime.c in Sources */, 4B41469C10BD3C4300C12F0C /* JackNetAPI.cpp in Sources */, 4B41469D10BD3C4300C12F0C /* JackNetInterface.cpp in Sources */, 4B41469E10BD3C4300C12F0C /* JackNetTool.cpp in Sources */, 4B41469F10BD3C4300C12F0C /* JackNetUnixSocket.cpp in Sources */, 4B4146A010BD3C4300C12F0C /* JackPosixThread.cpp in Sources */, 4B4146A210BD3C4300C12F0C /* JackAudioAdapterInterface.cpp in Sources */, 4B4146A310BD3C4300C12F0C /* JackResampler.cpp in Sources */, 4B4146A410BD3C4300C12F0C /* ringbuffer.c in Sources */, 4B4146A510BD3C4300C12F0C /* iPhoneNetAppDelegate.m in Sources */, 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */, 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */, 4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15F7C11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BCB37B7112D647C008C7BC1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */, 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15F7D11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BCF75DB10BC2FD90082C526 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BCF75DC10BC2FD90082C526 /* JackMachThread.cpp in Sources */, 4BCF75DD10BC2FD90082C526 /* JackMachTime.c in Sources */, 4BCF75DE10BC2FD90082C526 /* JackNetAPI.cpp in Sources */, 4BCF75DF10BC2FD90082C526 /* JackNetInterface.cpp in Sources */, 4BCF75E010BC2FD90082C526 /* JackNetTool.cpp in Sources */, 4BCF75E110BC2FD90082C526 /* JackNetUnixSocket.cpp in Sources */, 4BCF75E210BC2FD90082C526 /* JackPosixThread.cpp in Sources */, 4BCF75E410BC2FD90082C526 /* JackAudioAdapterInterface.cpp in Sources */, 4BCF75E510BC2FD90082C526 /* JackResampler.cpp in Sources */, 4BCF75E610BC2FD90082C526 /* ringbuffer.c in Sources */, 4BCF75E710BC2FD90082C526 /* iPhoneNetAppDelegate.m in Sources */, 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */, 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */, 4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15F7B11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BDFCD3F113DB6B700D77992 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BDFCD4A113DB6B700D77992 /* main_slave.mm in Sources */, 4BDFCD4B113DB6B700D77992 /* iPhoneNetAppDelegate.m in Sources */, 4BDFCD4D113DB6B700D77992 /* CAHostTimeBase.cpp in Sources */, 4BDFCD4E113DB6B700D77992 /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4BFF45610F4D5D9700106083 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4BFF45630F4D5D9700106083 /* JackMachThread.cpp in Sources */, 4BFF45640F4D5D9700106083 /* JackMachTime.c in Sources */, 4BFF45650F4D5D9700106083 /* JackNetAPI.cpp in Sources */, 4BFF45660F4D5D9700106083 /* JackNetInterface.cpp in Sources */, 4BFF45670F4D5D9700106083 /* JackNetTool.cpp in Sources */, 4BFF45680F4D5D9700106083 /* JackNetUnixSocket.cpp in Sources */, 4BFF45690F4D5D9700106083 /* JackPosixThread.cpp in Sources */, 4BFF456B0F4D5D9700106083 /* JackAudioAdapterInterface.cpp in Sources */, 4BFF456C0F4D5D9700106083 /* JackResampler.cpp in Sources */, 4BFF456D0F4D5D9700106083 /* ringbuffer.c in Sources */, 4B0773880F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */, 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */, 4BF15E2711356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15F7A11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 1D6058940D05DD3E006BFB54 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( /usr/local/include, ../../macosx/coreaudio, ../../macosx, ../../posix, ../../common/jack, ../../common, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/build/Debug-iphonesimulator\"", ); OTHER_LDFLAGS = libcelt.a; PRODUCT_NAME = NetJackSlave; SDKROOT = iphoneos3.1.3; }; name = Debug; }; 1D6058950D05DD3E006BFB54 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; GCC_THUMB_SUPPORT = NO; HEADER_SEARCH_PATHS = ( ., /usr/local/include, ../../macosx/coreaudio, ../../common/jack, ../../common, ../../posix, ../../macosx, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/build/Debug-iphonesimulator\"", ); OTHER_LDFLAGS = libcelt.a; PRODUCT_NAME = NetJackSlave; SDKROOT = iphoneos3.1.3; }; name = Release; }; 4B0772360F54018C000DC657 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( /usr/local/include, ../../macosx/coreaudio, ../../macosx, ../../posix, ../../common/jack, ../../common, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); OTHER_LDFLAGS = libcelt.a; PRODUCT_NAME = NetJackMaster; SDKROOT = iphoneos3.1.3; }; name = Debug; }; 4B0772370F54018C000DC657 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( /usr/local/include, ../../macosx/coreaudio, ../../common/jack, ../../common, ../../posix, ../../macosx, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); OTHER_LDFLAGS = libcelt.a; PRODUCT_NAME = NetJackMaster; }; name = Release; }; 4B1A94110F49BDE100D3626B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( /usr/local/include, ../../common/jack, ../../common, ../../posix, ../../macosx, ); MACH_O_TYPE = staticlib; PREBINDING = NO; PRODUCT_NAME = jacknet; SDKROOT = iphoneos3.1.3; STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static; }; name = Debug; }; 4B1A94120F49BDE100D3626B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( /usr/local/include, ../../macosx, ../../posix, ../../common, ../../common/jack, ); PREBINDING = NO; PRODUCT_NAME = jacknet; SDKROOT = iphoneos3.1.3; ZERO_LINK = NO; }; name = Release; }; 4B4146AE10BD3C4300C12F0C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Stéphane Letz (8LJEY2RN3N)"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( ../../macosx, ../../posix, ../../common/jack, ../../common, ); INFOPLIST_FILE = "Info copy 2.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", ); OTHER_LDFLAGS = ""; PRODUCT_NAME = iPhoneFaustNet; "PROVISIONING_PROFILE[sdk=iphoneos*]" = "CEF78041-8E2A-499D-BF7C-8A1B22B6C2AC"; SDKROOT = iphoneos2.2.1; }; name = Debug; }; 4B4146AF10BD3C4300C12F0C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( ../../macosx, ../../common/jack, ../../common, ../../posix, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", ); ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = iPhoneFaustNet; SDKROOT = iphoneos3.1.2; }; name = Release; }; 4BCB37CC112D647C008C7BC1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; GCC_THUMB_SUPPORT = NO; HEADER_SEARCH_PATHS = ( ../../macosx, ../../posix, ../../common/jack, ../../common, ); INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", ); OTHER_LDFLAGS = ""; PRODUCT_NAME = iPhoneFaust; SDKROOT = iphoneos3.1.3; }; name = Debug; }; 4BCB37CD112D647C008C7BC1 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; GCC_THUMB_SUPPORT = NO; HEADER_SEARCH_PATHS = ( ../../macosx, ../../common/jack, ../../common, ../../posix, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", ); ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = iPhoneFaust; SDKROOT = iphoneos3.1.3; }; name = Release; }; 4BCF75F010BC2FD90082C526 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( ../../macosx, ../../posix, ../../common/jack, ../../common, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", ); OTHER_LDFLAGS = ""; PRODUCT_NAME = iPhoneThruNet; SDKROOT = iphoneos2.2.1; }; name = Debug; }; 4BCF75F110BC2FD90082C526 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; GCC_VERSION = ""; HEADER_SEARCH_PATHS = ( ../../macosx, ../../common/jack, ../../common, ../../posix, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", ); ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = iPhoneFaustNet; }; name = Release; }; 4BDFCD55113DB6B700D77992 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( ../../macosx/coreaudio, ../../macosx, ../../posix, ../../common/jack, ../../common, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); OTHER_LDFLAGS = "-ljacknet"; PRODUCT_NAME = NetJackSlave; SDKROOT = iphoneos3.1.3; }; name = Debug; }; 4BDFCD56113DB6B700D77992 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( ../../macosx/coreaudio, ../../common/jack, ../../common, ../../posix, ../../macosx, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); OTHER_LDFLAGS = "-ljacknet"; PRODUCT_NAME = NetJackSlave; }; name = Release; }; 4BFF45750F4D5D9700106083 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( ../../macosx, ../../posix, ../../common/jack, ../../common, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); OTHER_LDFLAGS = ""; PRODUCT_NAME = iPhoneFaustNet; SDKROOT = iphoneos2.2.1; }; name = Debug; }; 4BFF45760F4D5D9700106083 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( ../../macosx, ../../common/jack, ../../common, ../../posix, ); INFOPLIST_FILE = Info.plist; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = iPhoneFaustNet; }; name = Release; }; C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; SDKROOT = iphoneos2.2.1; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; SDKROOT = iphoneos2.2.1; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "iPhoneNetSlave" */ = { isa = XCConfigurationList; buildConfigurations = ( 1D6058940D05DD3E006BFB54 /* Debug */, 1D6058950D05DD3E006BFB54 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4B0772350F54018C000DC657 /* Build configuration list for PBXNativeTarget "iPhoneNetMaster" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B0772360F54018C000DC657 /* Debug */, 4B0772370F54018C000DC657 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4B1A94130F49BDFF00D3626B /* Build configuration list for PBXNativeTarget "libjacknet" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B1A94110F49BDE100D3626B /* Debug */, 4B1A94120F49BDE100D3626B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4B4146AD10BD3C4300C12F0C /* Build configuration list for PBXNativeTarget "iPhoneFaustNet Distribution" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B4146AE10BD3C4300C12F0C /* Debug */, 4B4146AF10BD3C4300C12F0C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4BCB37CB112D647C008C7BC1 /* Build configuration list for PBXNativeTarget "iPhoneFaust" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BCB37CC112D647C008C7BC1 /* Debug */, 4BCB37CD112D647C008C7BC1 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4BCF75EF10BC2FD90082C526 /* Build configuration list for PBXNativeTarget "iPhoneThruNet" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BCF75F010BC2FD90082C526 /* Debug */, 4BCF75F110BC2FD90082C526 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4BDFCD54113DB6B700D77992 /* Build configuration list for PBXNativeTarget "iPhoneNetSlaveLib" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BDFCD55113DB6B700D77992 /* Debug */, 4BDFCD56113DB6B700D77992 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFF45750F4D5D9700106083 /* Debug */, 4BFF45760F4D5D9700106083 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneNet" */ = { isa = XCConfigurationList; buildConfigurations = ( C01FCF4F08A954540054247B /* Debug */, C01FCF5008A954540054247B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; } 1.9.12~dfsg/macosx/iphone/main_slave.mm0000644000000000000000000000623413214314510016572 0ustar rootroot// // main.m // iPhoneNet // // Created by Stéphane LETZ on 16/02/09. // Copyright Grame 2009. All rights reserved. // #import #include #include "TiPhoneCoreAudioRenderer.h" #define NUM_INPUT 0 #define NUM_OUTPUT 2 jack_net_slave_t* net = NULL; jack_adapter_t* adapter = NULL; int buffer_size; int sample_rate; static int net_process(jack_nframes_t buffer_size, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, void* data) { jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); // Process input, produce output if (audio_input == audio_output) { // Copy net input to net output for (int i = 0; i < audio_input; i++) { memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); } } return 0; } static void net_shutdown(void *arg) { if (adapter) jack_flush_adapter(adapter); } static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg) { jack_adapter_push_and_pull(adapter, inputs, outputs, frames); } //http://www.securityfocus.com/infocus/1884 #define WIFI_MTU 1500 int main(int argc, char *argv[]) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackCeltEncoder, 128, 2 }; jack_master_t result; //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) { printf("jack_net_slave_open error...\n"); return -1; } if ((adapter = jack_create_adapter(NUM_INPUT, NUM_OUTPUT, result.buffer_size, result.sample_rate, result.buffer_size, result.sample_rate)) == 0) { return -1; } TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); jack_set_net_slave_process_callback(net, net_process, NULL); jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); if (jack_net_slave_activate(net) != 0) { printf("Cannot activate slave client\n"); return -1; } if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) { return -1; } audio_device.SetAudioCallback(SlaveAudioCallback, NULL); if (audio_device.Start() < 0) { return -1; } int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; audio_device.Stop(); audio_device.Close(); // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net); jack_destroy_adapter(adapter); return retVal; } 1.9.12~dfsg/macosx/iphone/freeverb.mm0000644000000000000000000005504713214314510016262 0ustar rootroot//----------------------------------------------------- // name: "freeverb" // version: "1.0" // author: "Grame" // license: "BSD" // copyright: "(c)GRAME 2006" // // Code generated with Faust 0.9.9.5b2 (http://faust.grame.fr) //----------------------------------------------------- /* link with */ /* link with */ #include /* link with */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "JackAudioQueueAdapter.h" using namespace std; // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) // flags to avoid costly denormals #ifdef __SSE__ #include #ifdef __SSE2__ #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040) #else #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) #endif #else #define AVOIDDENORMALS #endif //#define BENCHMARKMODE struct Meta : map { void declare (const char* key, const char* value) { (*this)[key]=value; } }; #define max(x,y) (((x)>(y)) ? (x) : (y)) #define min(x,y) (((x)<(y)) ? (x) : (y)) inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); } inline int int2pow2 (int x) { int r = 0; while ((1< fPrefix; map fKeyParam; void addOption(const char* label, float* zone, float min, float max) { string fullname = fPrefix.top() + label; fKeyParam.insert(make_pair(fullname, param(zone, min, max))); } void openAnyBox(const char* label) { string prefix; if (label && label[0]) { prefix = fPrefix.top() + "-" + label; } else { prefix = fPrefix.top(); } fPrefix.push(prefix); } public: CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); } virtual ~CMDUI() {} virtual void addButton(const char* label, float* zone) {}; virtual void addToggleButton(const char* label, float* zone) {}; virtual void addCheckButton(const char* label, float* zone) {}; virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) { addOption(label,zone,min,max); } virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) { addOption(label,zone,min,max); } virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) { addOption(label,zone,min,max); } // -- passive widgets virtual void addNumDisplay(const char* label, float* zone, int precision) {} virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) {} virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) {} virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) {} virtual void openFrameBox(const char* label) { openAnyBox(label); } virtual void openTabBox(const char* label) { openAnyBox(label); } virtual void openHorizontalBox(const char* label) { openAnyBox(label); } virtual void openVerticalBox(const char* label) { openAnyBox(label); } virtual void closeBox() { fPrefix.pop(); } virtual void show() {} virtual void run() { char c; printf("Type 'q' to quit\n"); while ((c = getchar()) != 'q') { sleep(1); } } void print() { map::iterator i; cout << fArgc << "\n"; cout << fArgv[0] << " option list : "; for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) { cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] "; } } void process_command() { map::iterator p; for (int i = 1; i < fArgc; i++) { if (fArgv[i][0] == '-') { p = fKeyParam.find(fArgv[i]); if (p == fKeyParam.end()) { cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; print(); exit(1); } char* end; *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); i++; } } } void process_init() { map::iterator p; for (int i = 1; i < fArgc; i++) { if (fArgv[i][0] == '-') { p = fKeyParam.find(fArgv[i]); if (p == fKeyParam.end()) { cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; exit(1); } char* end; *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); i++; } } } }; //---------------------------------------------------------------- // Signal processor definition //---------------------------------------------------------------- class dsp { protected: int fSamplingFreq; public: dsp() {} virtual ~dsp() {} virtual int getNumInputs() = 0; virtual int getNumOutputs() = 0; virtual void buildUserInterface(UI* interface) = 0; virtual void init(int samplingRate) = 0; virtual void compute(int len, float** inputs, float** outputs) = 0; virtual void conclude() {} }; //---------------------------------------------------------------------------- // FAUST generated code //---------------------------------------------------------------------------- class mydsp : public dsp { private: float fslider0; float fRec9[2]; float fslider1; int IOTA; float fVec0[2048]; float fRec8[2]; float fRec11[2]; float fVec1[2048]; float fRec10[2]; float fRec13[2]; float fVec2[2048]; float fRec12[2]; float fRec15[2]; float fVec3[2048]; float fRec14[2]; float fRec17[2]; float fVec4[2048]; float fRec16[2]; float fRec19[2]; float fVec5[2048]; float fRec18[2]; float fRec21[2]; float fVec6[2048]; float fRec20[2]; float fRec23[2]; float fVec7[2048]; float fRec22[2]; float fVec8[1024]; float fRec6[2]; float fVec9[512]; float fRec4[2]; float fVec10[512]; float fRec2[2]; float fVec11[256]; float fRec0[2]; float fslider2; float fRec33[2]; float fVec12[2048]; float fRec32[2]; float fRec35[2]; float fVec13[2048]; float fRec34[2]; float fRec37[2]; float fVec14[2048]; float fRec36[2]; float fRec39[2]; float fVec15[2048]; float fRec38[2]; float fRec41[2]; float fVec16[2048]; float fRec40[2]; float fRec43[2]; float fVec17[2048]; float fRec42[2]; float fRec45[2]; float fVec18[2048]; float fRec44[2]; float fRec47[2]; float fVec19[2048]; float fRec46[2]; float fVec20[1024]; float fRec30[2]; float fVec21[512]; float fRec28[2]; float fVec22[512]; float fRec26[2]; float fVec23[256]; float fRec24[2]; public: static void metadata(Meta* m) { m->declare("name", "freeverb"); m->declare("version", "1.0"); m->declare("author", "Grame"); m->declare("license", "BSD"); m->declare("copyright", "(c)GRAME 2006"); } virtual int getNumInputs() { return 2; } virtual int getNumOutputs() { return 2; } static void classInit(int samplingFreq) { } virtual void instanceInit(int samplingFreq) { fSamplingFreq = samplingFreq; fslider0 = 0.5f; for (int i=0; i<2; i++) fRec9[i] = 0; fslider1 = 0.8f; IOTA = 0; for (int i=0; i<2048; i++) fVec0[i] = 0; for (int i=0; i<2; i++) fRec8[i] = 0; for (int i=0; i<2; i++) fRec11[i] = 0; for (int i=0; i<2048; i++) fVec1[i] = 0; for (int i=0; i<2; i++) fRec10[i] = 0; for (int i=0; i<2; i++) fRec13[i] = 0; for (int i=0; i<2048; i++) fVec2[i] = 0; for (int i=0; i<2; i++) fRec12[i] = 0; for (int i=0; i<2; i++) fRec15[i] = 0; for (int i=0; i<2048; i++) fVec3[i] = 0; for (int i=0; i<2; i++) fRec14[i] = 0; for (int i=0; i<2; i++) fRec17[i] = 0; for (int i=0; i<2048; i++) fVec4[i] = 0; for (int i=0; i<2; i++) fRec16[i] = 0; for (int i=0; i<2; i++) fRec19[i] = 0; for (int i=0; i<2048; i++) fVec5[i] = 0; for (int i=0; i<2; i++) fRec18[i] = 0; for (int i=0; i<2; i++) fRec21[i] = 0; for (int i=0; i<2048; i++) fVec6[i] = 0; for (int i=0; i<2; i++) fRec20[i] = 0; for (int i=0; i<2; i++) fRec23[i] = 0; for (int i=0; i<2048; i++) fVec7[i] = 0; for (int i=0; i<2; i++) fRec22[i] = 0; for (int i=0; i<1024; i++) fVec8[i] = 0; for (int i=0; i<2; i++) fRec6[i] = 0; for (int i=0; i<512; i++) fVec9[i] = 0; for (int i=0; i<2; i++) fRec4[i] = 0; for (int i=0; i<512; i++) fVec10[i] = 0; for (int i=0; i<2; i++) fRec2[i] = 0; for (int i=0; i<256; i++) fVec11[i] = 0; for (int i=0; i<2; i++) fRec0[i] = 0; fslider2 = 0.8f; for (int i=0; i<2; i++) fRec33[i] = 0; for (int i=0; i<2048; i++) fVec12[i] = 0; for (int i=0; i<2; i++) fRec32[i] = 0; for (int i=0; i<2; i++) fRec35[i] = 0; for (int i=0; i<2048; i++) fVec13[i] = 0; for (int i=0; i<2; i++) fRec34[i] = 0; for (int i=0; i<2; i++) fRec37[i] = 0; for (int i=0; i<2048; i++) fVec14[i] = 0; for (int i=0; i<2; i++) fRec36[i] = 0; for (int i=0; i<2; i++) fRec39[i] = 0; for (int i=0; i<2048; i++) fVec15[i] = 0; for (int i=0; i<2; i++) fRec38[i] = 0; for (int i=0; i<2; i++) fRec41[i] = 0; for (int i=0; i<2048; i++) fVec16[i] = 0; for (int i=0; i<2; i++) fRec40[i] = 0; for (int i=0; i<2; i++) fRec43[i] = 0; for (int i=0; i<2048; i++) fVec17[i] = 0; for (int i=0; i<2; i++) fRec42[i] = 0; for (int i=0; i<2; i++) fRec45[i] = 0; for (int i=0; i<2048; i++) fVec18[i] = 0; for (int i=0; i<2; i++) fRec44[i] = 0; for (int i=0; i<2; i++) fRec47[i] = 0; for (int i=0; i<2048; i++) fVec19[i] = 0; for (int i=0; i<2; i++) fRec46[i] = 0; for (int i=0; i<1024; i++) fVec20[i] = 0; for (int i=0; i<2; i++) fRec30[i] = 0; for (int i=0; i<512; i++) fVec21[i] = 0; for (int i=0; i<2; i++) fRec28[i] = 0; for (int i=0; i<512; i++) fVec22[i] = 0; for (int i=0; i<2; i++) fRec26[i] = 0; for (int i=0; i<256; i++) fVec23[i] = 0; for (int i=0; i<2; i++) fRec24[i] = 0; } virtual void init(int samplingFreq) { classInit(samplingFreq); instanceInit(samplingFreq); } virtual void buildUserInterface(UI* interface) { interface->openVerticalBox("Freeverb"); interface->addHorizontalSlider("Damp", &fslider0, 0.5f, 0.0f, 1.0f, 2.500000e-02f); interface->addHorizontalSlider("RoomSize", &fslider1, 0.8f, 0.0f, 1.0f, 2.500000e-02f); interface->addHorizontalSlider("Wet", &fslider2, 0.8f, 0.0f, 1.0f, 2.500000e-02f); interface->closeBox(); } virtual void compute (int count, float** input, float** output) { float fSlow0 = (0.4f * fslider0); float fSlow1 = (1 - fSlow0); float fSlow2 = (0.7f + (0.28f * fslider1)); float fSlow3 = fslider2; float fSlow4 = (1 - fSlow3); float* input0 = input[0]; float* input1 = input[1]; float* output0 = output[0]; float* output1 = output[1]; for (int i=0; ihi) hi = m; tot += m; } cout << low << ' ' << tot/(mesure-KSKIP) << ' ' << hi << endl; } else { for (int i = KSKIP+1; ihi) hi = m; tot += m; } cout << low << ' ' << tot/(KMESURE-KSKIP) << ' ' << hi << endl; } } #else #define STARTMESURE #define STOPMESURE #endif static int net_process(jack_nframes_t buffer_size, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, void* data) { AVOIDDENORMALS; STARTMESURE DSP.compute(buffer_size, audio_input_buffer, audio_output_buffer); STOPMESURE return 0; } /****************************************************************************** ******************************************************************************* MAIN PLAY THREAD ******************************************************************************* *******************************************************************************/ //------------------------------------------------------------------------- // MAIN //------------------------------------------------------------------------- #define TEST_MASTER "194.5.49.5" int main(int argc, char *argv[]) { UI* interface = new CMDUI(argc, argv); jack_net_slave_t* net; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //Jack::JackAudioQueueAdapter audio(2, 2, 1024, 44100, NULL); gNumInChans = DSP.getNumInputs(); gNumOutChans = DSP.getNumOutputs(); jack_slave_t request = { gNumInChans, gNumOutChans, 0, 0, DEFAULT_MTU, -1, 2 }; jack_master_t result; printf("Network\n"); //if (audio.Open() < 0) { // fprintf(stderr, "Cannot open audio\n"); // return 1; //} //audio.Start(); // Hang around forever... //while(1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false); if ((net = jack_net_slave_open(TEST_MASTER, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { fprintf(stderr, "jack remote server not running ?\n"); return 1; } jack_set_net_slave_process_callback(net, net_process, NULL); // We want to restart (that is "wait for available master" again) //jack_set_net_shutdown_callback(net, net_shutdown, 0); DSP.init(result.sample_rate); DSP.buildUserInterface(interface); if (jack_net_slave_activate(net) != 0) { fprintf(stderr, "cannot activate net"); return 1; } int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net); //if (audio.Close() < 0) { // fprintf(stderr, "Cannot close audio\n"); //} return retVal; } 1.9.12~dfsg/macosx/JackCompilerDeps_os.h0000644000000000000000000000231413214314510016663 0ustar rootroot/* Copyright (C) 2004-2005 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCompilerDeps_APPLE__ #define __JackCompilerDeps_APPLE__ #include "JackConstants.h" #if __GNUC__ #define MEM_ALIGN(x,y) x __attribute__((aligned(y))) #define LIB_EXPORT __attribute__((visibility("default"))) #ifdef SERVER_SIDE #define SERVER_EXPORT __attribute__((visibility("default"))) #else #define SERVER_EXPORT #endif #else #define MEM_ALIGN(x,y) x #define LIB_EXPORT #define SERVER_EXPORT /* Add other things here for non-gcc platforms */ #endif #endif 1.9.12~dfsg/macosx/JackMachTime.c0000644000000000000000000000271113214314510015257 0ustar rootroot/* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackTime.h" #include "JackError.h" #include "JackTypes.h" #include #include static double __jack_time_ratio; SERVER_EXPORT void JackSleep(long usec) { usleep(usec); } /* This should only be called ONCE per process. */ SERVER_EXPORT void InitTime() { mach_timebase_info_data_t info; mach_timebase_info(&info); __jack_time_ratio = ((double)info.numer / (double)info.denom) / 1000; } SERVER_EXPORT void EndTime() {} SERVER_EXPORT jack_time_t GetMicroSeconds(void) { return (jack_time_t) (mach_absolute_time() * __jack_time_ratio); } void SetClockSource(jack_timer_type_t source) {} const char* ClockSourceName(jack_timer_type_t source) { return ""; } 1.9.12~dfsg/macosx/Jack-Info.plist0000644000000000000000000000140313214314510015446 0ustar rootroot CFBundleDevelopmentRegion English CFBundleExecutable Jackservermp CFBundleGetInfoString Jackdmp 1.9.12, @03-17 Paul Davis, Grame, Filipe Coelho CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType FMWK CFBundleShortVersionString CFBundleSignature ???? CFBundleVersion 1.9.12 1.9.12~dfsg/macosx/JackMachThread.mm0000644000000000000000000002150313214314510015757 0ustar rootroot/* Copyright (C) 2001 Paul Davis Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackMachThread.h" #include "JackError.h" #ifdef MY_TARGET_OS_IPHONE #include "/Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.h" #endif namespace Jack { int JackMachThread::SetThreadToPriority(jack_native_thread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint) { if (inPriority == 96) { // REAL-TIME / TIME-CONSTRAINT THREAD thread_time_constraint_policy_data_t theTCPolicy; #ifdef MY_TARGET_OS_IPHONE theTCPolicy.period = CAHostTimeBase::ConvertFromNanos(period); theTCPolicy.computation = CAHostTimeBase::ConvertFromNanos(computation); theTCPolicy.constraint = CAHostTimeBase::ConvertFromNanos(constraint); #else theTCPolicy.period = AudioConvertNanosToHostTime(period); theTCPolicy.computation = AudioConvertNanosToHostTime(computation); theTCPolicy.constraint = AudioConvertNanosToHostTime(constraint); #endif theTCPolicy.preemptible = true; kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) &theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); jack_log("JackMachThread::thread_policy_set res = %ld", res); return (res == KERN_SUCCESS) ? 0 : -1; } else { // OTHER THREADS thread_extended_policy_data_t theFixedPolicy; thread_precedence_policy_data_t thePrecedencePolicy; SInt32 relativePriority; // [1] SET FIXED / NOT FIXED theFixedPolicy.timeshare = !inIsFixed; thread_policy_set(pthread_mach_thread_np(thread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT); // [2] SET PRECEDENCE // N.B.: We expect that if thread A created thread B, and the program wishes to change // the priority of thread B, then the call to change the priority of thread B must be // made by thread A. // This assumption allows us to use pthread_self() to correctly calculate the priority // of the feeder thread (since precedency policy's importance is relative to the // spawning thread's priority.) relativePriority = inPriority - GetThreadSetPriority(pthread_self()); thePrecedencePolicy.importance = relativePriority; kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_PRECEDENCE_POLICY, (thread_policy_t) &thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); jack_log("JackMachThread::thread_policy_set res = %ld", res); return (res == KERN_SUCCESS) ? 0 : -1; } } // returns the thread's priority as it was last set by the API UInt32 JackMachThread::GetThreadSetPriority(jack_native_thread_t thread) { return GetThreadPriority(thread, THREAD_SET_PRIORITY); } // returns the thread's priority as it was last scheduled by the Kernel UInt32 JackMachThread::GetThreadScheduledPriority(jack_native_thread_t thread) { return GetThreadPriority(thread, THREAD_SCHEDULED_PRIORITY); } UInt32 JackMachThread::GetThreadPriority(jack_native_thread_t thread, int inWhichPriority) { thread_basic_info_data_t threadInfo; policy_info_data_t thePolicyInfo; unsigned int count; // get basic info count = THREAD_BASIC_INFO_COUNT; thread_info(pthread_mach_thread_np(thread), THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &count); switch (threadInfo.policy) { case POLICY_TIMESHARE: count = POLICY_TIMESHARE_INFO_COUNT; thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&(thePolicyInfo.ts), &count); if (inWhichPriority == THREAD_SCHEDULED_PRIORITY) { return thePolicyInfo.ts.cur_priority; } else { return thePolicyInfo.ts.base_priority; } break; case POLICY_FIFO: count = POLICY_FIFO_INFO_COUNT; thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_FIFO_INFO, (thread_info_t)&(thePolicyInfo.fifo), &count); if ( (thePolicyInfo.fifo.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { return thePolicyInfo.fifo.depress_priority; } return thePolicyInfo.fifo.base_priority; break; case POLICY_RR: count = POLICY_RR_INFO_COUNT; thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_RR_INFO, (thread_info_t)&(thePolicyInfo.rr), &count); if ( (thePolicyInfo.rr.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { return thePolicyInfo.rr.depress_priority; } return thePolicyInfo.rr.base_priority; break; } return 0; } int JackMachThread::GetParams(jack_native_thread_t thread, UInt64* period, UInt64* computation, UInt64* constraint) { thread_time_constraint_policy_data_t theTCPolicy; mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT; boolean_t get_default = false; kern_return_t res = thread_policy_get(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) & theTCPolicy, &count, &get_default); if (res == KERN_SUCCESS) { #ifdef MY_TARGET_OS_IPHONE *period = CAHostTimeBase::ConvertToNanos(theTCPolicy.period); *computation = CAHostTimeBase::ConvertToNanos(theTCPolicy.computation); *constraint = CAHostTimeBase::ConvertToNanos(theTCPolicy.constraint); #else *period = AudioConvertHostTimeToNanos(theTCPolicy.period); *computation = AudioConvertHostTimeToNanos(theTCPolicy.computation); *constraint = AudioConvertHostTimeToNanos(theTCPolicy.constraint); #endif jack_log("JackMachThread::GetParams period = %ld computation = %ld constraint = %ld", long(*period / 1000.0f), long(*computation / 1000.0f), long(*constraint / 1000.0f)); return 0; } else { return -1; } } int JackMachThread::Kill() { if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackMachThread::Kill"); mach_port_t machThread = pthread_mach_thread_np(fThread); int res = (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1; fStatus = kIdle; fThread = (jack_native_thread_t)NULL; return res; } else { return -1; } } int JackMachThread::AcquireRealTime() { jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; } int JackMachThread::AcquireSelfRealTime() { jack_log("JackMachThread::AcquireSelfRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); return AcquireRealTimeImp(pthread_self(), fPeriod, fComputation, fConstraint); } int JackMachThread::AcquireRealTime(int priority) { fPriority = priority; return AcquireRealTime(); } int JackMachThread::AcquireSelfRealTime(int priority) { fPriority = priority; return AcquireSelfRealTime(); } int JackMachThread::AcquireRealTimeImp(jack_native_thread_t thread, UInt64 period, UInt64 computation, UInt64 constraint) { SetThreadToPriority(thread, 96, true, period, computation, constraint); return 0; } int JackMachThread::DropRealTime() { return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1; } int JackMachThread::DropSelfRealTime() { return DropRealTimeImp(pthread_self()); } int JackMachThread::DropRealTimeImp(jack_native_thread_t thread) { SetThreadToPriority(thread, 63, false, 0, 0, 0); return 0; } void JackMachThread::SetParams(UInt64 period, UInt64 computation, UInt64 constraint) { fPeriod = period; fComputation = computation; fConstraint = constraint; } } // end of namespace 1.9.12~dfsg/macosx/coreaudio/0000755000000000000000000000000013214314510014604 5ustar rootroot1.9.12~dfsg/macosx/coreaudio/JackCoreAudioDriver.h0000644000000000000000000001704713214314510020605 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreAudioDriver__ #define __JackCoreAudioDriver__ #include #include #include #include "JackAudioDriver.h" #include "JackTime.h" #include using namespace std; namespace Jack { #define kVersion 102 typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01) #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) #define WAIT_COUNTER 60 #define WAIT_NOTIFICATION_COUNTER 30 /*! \brief The CoreAudio driver. \todo hardware monitoring */ class JackAC3Encoder; class JackCoreAudioDriver : public JackAudioDriver { private: JackAC3Encoder* fAC3Encoder; AudioUnit fAUHAL; AudioBufferList* fJackInputData; AudioBufferList* fDriverOutputData; AudioDeviceID fDeviceID; // Used "duplex" device AudioObjectID fPluginID; // Used for aggregate device AudioUnitRenderActionFlags* fActionFags; const AudioTimeStamp* fCurrentTime; bool fState; bool fHogged; char fCaptureUID[256]; char fPlaybackUID[256]; float fIOUsage; float fComputationGrain; bool fClockDriftCompensate; bool fDigitalPlayback; static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); static OSStatus AudioHardwareNotificationCallback(AudioHardwarePropertyID inPropertyID,void* inClientData); static OSStatus DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData); static OSStatus SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData); static OSStatus BSNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData); OSStatus GetDeviceIDFromUID(const char* UID, AudioDeviceID* id); OSStatus GetDefaultDevice(AudioDeviceID* id); OSStatus GetDefaultInputDevice(AudioDeviceID* id); OSStatus GetDefaultOutputDevice(AudioDeviceID* id); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector& latencies); // Setup OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus DestroyAggregateDevice(); bool IsAggregateDevice(AudioDeviceID device); int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name, jack_nframes_t samplerate, bool ac3_encoding); int SetupChannels(bool capturing, bool playing, int& inchannels, int& outchannels, int& in_nChannels, int& out_nChannels, bool strict); int SetupBuffers(int inchannels); void DisposeBuffers(); int SetupBufferSize(jack_nframes_t buffer_size); int SetupSampleRate(jack_nframes_t samplerate); int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate); int OpenAUHAL(bool capturing, bool playing, int inchannels, int outchannels, int in_nChannels, int out_nChannels, const vector& chan_in_list, const vector& chan_out_list, jack_nframes_t nframes, jack_nframes_t samplerate); void CloseAUHAL(); int AddListeners(); void RemoveListeners(); bool TakeHogAux(AudioDeviceID deviceID, bool isInput); bool TakeHog(); void UpdateLatencies(); bool IsDigitalDevice(AudioDeviceID device); OSStatus Render(AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, AudioBufferList* ioData); public: JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); virtual ~JackCoreAudioDriver(); int Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, int inchannels, int outchannels, const char* chan_in_list, const char* chan_out_list, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, int async_output_latency, int computation_grain, bool hogged, bool clock_drift, bool ac3_encoding, int ac3_bitrate, bool ac3_lfe); int Close(); int Attach(); int Start(); int Stop(); int Read(); int Write(); // BufferSize can be changed bool IsFixedBufferSize() { return false; } int SetBufferSize(jack_nframes_t buffer_size); }; } // end of namespace #endif 1.9.12~dfsg/macosx/coreaudio/JackCoreAudioDriver.mm0000644000000000000000000032335313214314510020767 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackCoreAudioDriver.h" #include "JackEngineControl.h" #include "JackMachThread.h" #include "JackGraphManager.h" #include "JackError.h" #include "JackClientControl.h" #include "JackDriverLoader.h" #include "JackGlobals.h" #include "JackTools.h" #include "JackLockedEngine.h" #include "JackAC3Encoder.h" #include #include #include #include namespace Jack { static void Print4CharCode(const char* msg, long c) { UInt32 __4CC_number = (c); char __4CC_string[5]; *((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number); __4CC_string[4] = 0; jack_log("%s'%s'", (msg), __4CC_string); } static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) { jack_log("- - - - - - - - - - - - - - - - - - - -"); jack_log(" Sample Rate:%f", inDesc->mSampleRate); jack_log(" Format ID:%.*s", (int)sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); jack_log(" Format Flags:%lX", inDesc->mFormatFlags); jack_log(" Bytes per Packet:%ld", inDesc->mBytesPerPacket); jack_log(" Frames per Packet:%ld", inDesc->mFramesPerPacket); jack_log(" Bytes per Frame:%ld", inDesc->mBytesPerFrame); jack_log(" Channels per Frame:%ld", inDesc->mChannelsPerFrame); jack_log(" Bits per Channel:%ld", inDesc->mBitsPerChannel); jack_log("- - - - - - - - - - - - - - - - - - - -"); } static void printError(OSStatus err) { switch (err) { case kAudioHardwareNoError: jack_log("error code : kAudioHardwareNoError"); break; case kAudioConverterErr_FormatNotSupported: jack_log("error code : kAudioConverterErr_FormatNotSupported"); break; case kAudioConverterErr_OperationNotSupported: jack_log("error code : kAudioConverterErr_OperationNotSupported"); break; case kAudioConverterErr_PropertyNotSupported: jack_log("error code : kAudioConverterErr_PropertyNotSupported"); break; case kAudioConverterErr_InvalidInputSize: jack_log("error code : kAudioConverterErr_InvalidInputSize"); break; case kAudioConverterErr_InvalidOutputSize: jack_log("error code : kAudioConverterErr_InvalidOutputSize"); break; case kAudioConverterErr_UnspecifiedError: jack_log("error code : kAudioConverterErr_UnspecifiedError"); break; case kAudioConverterErr_BadPropertySizeError: jack_log("error code : kAudioConverterErr_BadPropertySizeError"); break; case kAudioConverterErr_RequiresPacketDescriptionsError: jack_log("error code : kAudioConverterErr_RequiresPacketDescriptionsError"); break; case kAudioConverterErr_InputSampleRateOutOfRange: jack_log("error code : kAudioConverterErr_InputSampleRateOutOfRange"); break; case kAudioConverterErr_OutputSampleRateOutOfRange: jack_log("error code : kAudioConverterErr_OutputSampleRateOutOfRange"); break; case kAudioHardwareNotRunningError: jack_log("error code : kAudioHardwareNotRunningError"); break; case kAudioHardwareUnknownPropertyError: jack_log("error code : kAudioHardwareUnknownPropertyError"); break; case kAudioHardwareIllegalOperationError: jack_log("error code : kAudioHardwareIllegalOperationError"); break; case kAudioHardwareBadDeviceError: jack_log("error code : kAudioHardwareBadDeviceError"); break; case kAudioHardwareBadStreamError: jack_log("error code : kAudioHardwareBadStreamError"); break; case kAudioDeviceUnsupportedFormatError: jack_log("error code : kAudioDeviceUnsupportedFormatError"); break; case kAudioDevicePermissionsError: jack_log("error code : kAudioDevicePermissionsError"); break; case kAudioHardwareBadObjectError: jack_log("error code : kAudioHardwareBadObjectError"); break; case kAudioHardwareUnsupportedOperationError: jack_log("error code : kAudioHardwareUnsupportedOperationError"); break; default: Print4CharCode("error code : unknown ", err); break; } } static bool CheckAvailableDeviceName(const char* device_name, AudioDeviceID* device_id) { UInt32 size; Boolean isWritable; int i, deviceNum; OSStatus err; err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); if (err != noErr) { return false; } deviceNum = size / sizeof(AudioDeviceID); AudioDeviceID devices[deviceNum]; err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); if (err != noErr) { return false; } for (i = 0; i < deviceNum; i++) { char device_name_aux[256]; size = 256; err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name_aux); if (err != noErr) { return false; } if (strncmp(device_name_aux, device_name, strlen(device_name)) == 0) { *device_id = devices[i]; return true; } } return false; } static bool CheckAvailableDevice(AudioDeviceID device_id) { UInt32 size; Boolean isWritable; int i, deviceNum; OSStatus err; err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); if (err != noErr) { return false; } deviceNum = size / sizeof(AudioDeviceID); AudioDeviceID devices[deviceNum]; err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); if (err != noErr) { return false; } for (i = 0; i < deviceNum; i++) { if (device_id == devices[i]) { return true; } } return false; } static OSStatus DisplayDeviceNames() { UInt32 size; Boolean isWritable; int i, deviceNum; OSStatus err; CFStringRef UIname; err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); if (err != noErr) { return err; } deviceNum = size / sizeof(AudioDeviceID); AudioDeviceID devices[deviceNum]; err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); if (err != noErr) { return err; } for (i = 0; i < deviceNum; i++) { char device_name[256]; char internal_name[256]; size = sizeof(CFStringRef); UIname = NULL; err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); if (err == noErr) { CFStringGetCString(UIname, internal_name, 256, CFStringGetSystemEncoding()); } else { goto error; } size = 256; err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name); if (err != noErr) { return err; } jack_info("Device ID = \'%d\' name = \'%s\', internal name = \'%s\' (to be used as -C, -P, or -d parameter)", devices[i], device_name, internal_name); } return noErr; error: if (UIname != NULL) { CFRelease(UIname); } return err; } static CFStringRef GetDeviceName(AudioDeviceID id) { UInt32 size = sizeof(CFStringRef); CFStringRef UIname; OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); return (err == noErr) ? UIname : NULL; } static void ParseChannelList(const string& list, vector& result, int max_chan) { stringstream ss(list); string token; int chan; while (ss >> token) { istringstream ins; ins.str(token); ins >> chan; if (chan < 0 || chan >= max_chan) { jack_error("Ignore incorrect channel mapping value = %d", chan); } else { result.push_back(chan); } } } OSStatus JackCoreAudioDriver::Render(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData) { return static_cast(inRefCon)->Render(ioActionFlags, inTimeStamp, ioData); } OSStatus JackCoreAudioDriver::Render(AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, AudioBufferList* ioData) { fActionFags = ioActionFlags; fCurrentTime = inTimeStamp; fDriverOutputData = ioData; // Setup threaded based log function et get RT thread parameters once... if (set_threaded_log_function()) { jack_log("JackCoreAudioDriver::Render : set_threaded_log_function"); JackMachThread::GetParams(pthread_self(), &fEngineControl->fPeriod, &fEngineControl->fComputation, &fEngineControl->fConstraint); if (fComputationGrain > 0) { jack_log("JackCoreAudioDriver::Render : RT thread computation setup to %d percent of period", int(fComputationGrain * 100)); fEngineControl->fComputation = fEngineControl->fPeriod * fComputationGrain; } } // Signal waiting start function... fState = true; CycleTakeBeginTime(); if (Process() < 0) { jack_error("Process error, stopping driver"); NotifyFailure(JackFailure | JackBackendError, "Process error, stopping driver"); // Message length limited to JACK_MESSAGE_SIZE Stop(); kill(JackTools::GetPID(), SIGINT); return kAudioHardwareUnsupportedOperationError; } else { return noErr; } } int JackCoreAudioDriver::Read() { if (fCaptureChannels > 0) { // Calling AudioUnitRender with no input returns a '????' error (callback setting issue ??), so hack to avoid it here... return (AudioUnitRender(fAUHAL, fActionFags, fCurrentTime, 1, fEngineControl->fBufferSize, fJackInputData) == noErr) ? 0 : -1; } else { return 0; } } int JackCoreAudioDriver::Write() { int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; if (fAC3Encoder) { // AC3 encoding and SPDIF write jack_default_audio_sample_t* AC3_inputs[MAX_AC3_CHANNELS]; jack_default_audio_sample_t* AC3_outputs[2]; for (int i = 0; i < fPlaybackChannels; i++) { AC3_inputs[i] = GetOutputBuffer(i); // If not connected, clear the buffer if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) == 0) { memset(AC3_inputs[i], 0, size); } } AC3_outputs[0] = (jack_default_audio_sample_t*)fDriverOutputData->mBuffers[0].mData; AC3_outputs[1] = (jack_default_audio_sample_t*)fDriverOutputData->mBuffers[1].mData; fAC3Encoder->Process(AC3_inputs, AC3_outputs, fEngineControl->fBufferSize); } else { // Standard write for (int i = 0; i < fPlaybackChannels; i++) { if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { jack_default_audio_sample_t* buffer = GetOutputBuffer(i); memcpy((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, buffer, size); // Monitor ports if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) { memcpy(GetMonitorBuffer(i), buffer, size); } } else { memset((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, 0, size); } } } return 0; } OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { case kAudioDevicePropertyNominalSampleRate: { jack_log("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); // Check new sample rate Float64 tmp_sample_rate; UInt32 outSize = sizeof(Float64); OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &tmp_sample_rate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); } else { jack_log("JackCoreAudioDriver::SRNotificationCallback : checked sample rate = %f", tmp_sample_rate); } driver->fState = true; break; } } return noErr; } OSStatus JackCoreAudioDriver::BSNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { case kAudioDevicePropertyBufferFrameSize: { jack_log("JackCoreAudioDriver::BSNotificationCallback kAudioDevicePropertyBufferFrameSize"); // Check new buffer size UInt32 tmp_buffer_size; UInt32 outSize = sizeof(UInt32); OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &tmp_buffer_size); if (err != noErr) { jack_error("Cannot get current buffer size"); printError(err); } else { jack_log("JackCoreAudioDriver::BSNotificationCallback : checked buffer size = %d", tmp_buffer_size); } driver->fState = true; break; } } return noErr; } // A better implementation would possibly try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) OSStatus JackCoreAudioDriver::AudioHardwareNotificationCallback(AudioHardwarePropertyID inPropertyID, void* inClientData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { case kAudioHardwarePropertyDevices: { jack_log("JackCoreAudioDriver::AudioHardwareNotificationCallback kAudioHardwarePropertyDevices"); DisplayDeviceNames(); AudioDeviceID captureID, playbackID; if (CheckAvailableDevice(driver->fDeviceID) || (CheckAvailableDeviceName(driver->fCaptureUID, &captureID) && CheckAvailableDeviceName(driver->fPlaybackUID, &playbackID))) { } break; } } return noErr; } OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { case kAudioDevicePropertyDeviceIsRunning: { UInt32 isrunning = 0; UInt32 outsize = sizeof(UInt32); if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunning, &outsize, &isrunning) == noErr) { jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceIsRunning = %d", isrunning); } break; } case kAudioDevicePropertyDeviceIsAlive: { UInt32 isalive = 0; UInt32 outsize = sizeof(UInt32); if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsAlive, &outsize, &isalive) == noErr) { jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceIsAlive = %d", isalive); } break; } case kAudioDevicePropertyDeviceHasChanged: { UInt32 hachanged = 0; UInt32 outsize = sizeof(UInt32); if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceHasChanged, &outsize, &hachanged) == noErr) { jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceHasChanged = %d", hachanged); } break; } case kAudioDeviceProcessorOverload: { jack_error("DeviceNotificationCallback kAudioDeviceProcessorOverload"); jack_time_t cur_time = GetMicroSeconds(); driver->NotifyXRun(cur_time, float(cur_time - driver->fBeginDateUst)); // Better this value than nothing... break; } case kAudioDevicePropertyStreamConfiguration: { jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration : server will quit..."); driver->NotifyFailure(JackFailure | JackBackendError, "Another application has changed the device configuration"); // Message length limited to JACK_MESSAGE_SIZE driver->CloseAUHAL(); kill(JackTools::GetPID(), SIGINT); return kAudioHardwareUnsupportedOperationError; } case kAudioDevicePropertyNominalSampleRate: { Float64 sample_rate = 0; UInt32 outsize = sizeof(Float64); OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate); if (err != noErr) { return kAudioHardwareUnsupportedOperationError; } char device_name[256]; const char* digidesign_name = "Digidesign"; driver->GetDeviceNameFromID(driver->fDeviceID, device_name); if (sample_rate != driver->fEngineControl->fSampleRate) { // Digidesign hardware, so "special" code : change the SR again here if (strncmp(device_name, digidesign_name, 10) == 0) { jack_log("JackCoreAudioDriver::DeviceNotificationCallback Digidesign HW = %s", device_name); // Set sample rate again... sample_rate = driver->fEngineControl->fSampleRate; err = AudioDeviceSetProperty(driver->fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outsize, &sample_rate); if (err != noErr) { jack_error("Cannot set sample rate = %f", sample_rate); printError(err); } else { jack_log("JackCoreAudioDriver::DeviceNotificationCallback : set sample rate = %f", sample_rate); } // Check new sample rate again... outsize = sizeof(Float64); err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); } else { jack_log("JackCoreAudioDriver::DeviceNotificationCallback : checked sample rate = %f", sample_rate); } return noErr; } else { driver->NotifyFailure(JackFailure | JackBackendError, "Another application has changed the sample rate"); // Message length limited to JACK_MESSAGE_SIZE driver->CloseAUHAL(); kill(JackTools::GetPID(), SIGINT); return kAudioHardwareUnsupportedOperationError; } } } } return noErr; } OSStatus JackCoreAudioDriver::GetDeviceIDFromUID(const char* UID, AudioDeviceID* id) { UInt32 size = sizeof(AudioValueTranslation); CFStringRef inIUD = CFStringCreateWithCString(NULL, UID, CFStringGetSystemEncoding()); AudioValueTranslation value = { &inIUD, sizeof(CFStringRef), id, sizeof(AudioDeviceID) }; if (inIUD == NULL) { return kAudioHardwareUnspecifiedError; } else { OSStatus res = AudioHardwareGetProperty(kAudioHardwarePropertyDeviceForUID, &size, &value); CFRelease(inIUD); jack_log("JackCoreAudioDriver::GetDeviceIDFromUID %s %ld", UID, *id); return (*id == kAudioDeviceUnknown) ? kAudioHardwareBadDeviceError : res; } } OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID* id) { OSStatus res; UInt32 theSize = sizeof(UInt32); AudioDeviceID inDefault; AudioDeviceID outDefault; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) { return res; } if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) { return res; } jack_log("JackCoreAudioDriver::GetDefaultDevice : input = %ld output = %ld", inDefault, outDefault); // Get the device only if default input and output are the same if (inDefault != outDefault) { jack_error("Default input and output devices are not the same !!"); return kAudioHardwareBadDeviceError; } else if (inDefault == 0) { jack_error("Default input and output devices are null !!"); return kAudioHardwareBadDeviceError; } else { *id = inDefault; return noErr; } } OSStatus JackCoreAudioDriver::GetDefaultInputDevice(AudioDeviceID* id) { OSStatus res; UInt32 theSize = sizeof(UInt32); AudioDeviceID inDefault; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) { return res; } if (inDefault == 0) { jack_error("Error default input device is 0, will take 'Built-in'..."); if (CheckAvailableDeviceName("Built-in Microphone", id) || CheckAvailableDeviceName("Built-in Line", id)) { jack_log("JackCoreAudioDriver::GetDefaultInputDevice : output = %ld", *id); return noErr; } else { jack_error("Cannot find any input device to use..."); return -1; } } jack_log("JackCoreAudioDriver::GetDefaultInputDevice : input = %ld ", inDefault); *id = inDefault; return noErr; } OSStatus JackCoreAudioDriver::GetDefaultOutputDevice(AudioDeviceID* id) { OSStatus res; UInt32 theSize = sizeof(UInt32); AudioDeviceID outDefault; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) { return res; } if (outDefault == 0) { jack_error("Error default ouput device is 0, will take 'Built-in'..."); if (CheckAvailableDeviceName("Built-in Output", id)) { jack_log("JackCoreAudioDriver::GetDefaultOutputDevice : output = %ld", *id); return noErr; } else { jack_error("Cannot find any output device to use..."); return -1; } } jack_log("JackCoreAudioDriver::GetDefaultOutputDevice : output = %ld", outDefault); *id = outDefault; return noErr; } OSStatus JackCoreAudioDriver::GetDeviceNameFromID(AudioDeviceID id, char* name) { UInt32 size = 256; return AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, name); } OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput) { OSStatus err = noErr; UInt32 outSize; Boolean outWritable; channelCount = 0; err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); if (err == noErr) { int stream_count = outSize / sizeof(AudioBufferList); jack_log("JackCoreAudioDriver::GetTotalChannels stream_count = %d", stream_count); AudioBufferList bufferList[stream_count]; err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); if (err == noErr) { for (uint i = 0; i < bufferList->mNumberBuffers; i++) { channelCount += bufferList->mBuffers[i].mNumberChannels; jack_log("JackCoreAudioDriver::GetTotalChannels stream = %d channels = %d", i, bufferList->mBuffers[i].mNumberChannels); } } } return err; } OSStatus JackCoreAudioDriver::GetStreamLatencies(AudioDeviceID device, bool isInput, vector& latencies) { OSStatus err = noErr; UInt32 outSize1, outSize2, outSize3; Boolean outWritable; err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, &outWritable); if (err == noErr) { int stream_count = outSize1 / sizeof(UInt32); AudioStreamID streamIDs[stream_count]; AudioBufferList bufferList[stream_count]; UInt32 streamLatency; outSize2 = sizeof(UInt32); err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, streamIDs); if (err != noErr) { jack_error("GetStreamLatencies kAudioDevicePropertyStreams err = %d", err); return err; } err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, &outWritable); if (err != noErr) { jack_error("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err); return err; } for (int i = 0; i < stream_count; i++) { err = AudioStreamGetProperty(streamIDs[i], 0, kAudioStreamPropertyLatency, &outSize2, &streamLatency); if (err != noErr) { jack_error("GetStreamLatencies kAudioStreamPropertyLatency err = %d", err); return err; } err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, bufferList); if (err != noErr) { jack_error("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err); return err; } // Push 'channel' time the stream latency for (uint k = 0; k < bufferList->mBuffers[i].mNumberChannels; k++) { latencies.push_back(streamLatency); } } } return err; } bool JackCoreAudioDriver::IsDigitalDevice(AudioDeviceID device) { OSStatus err = noErr; UInt32 outSize1; bool is_digital = false; /* Get a list of all the streams on this device */ AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectGetPropertyDataSize(device, &streamsAddress, 0, NULL, &outSize1); if (err != noErr) { jack_error("IsDigitalDevice kAudioDevicePropertyStreams err = %d", err); return false; } int stream_count = outSize1 / sizeof(AudioStreamID); AudioStreamID streamIDs[stream_count]; err = AudioObjectGetPropertyData(device, &streamsAddress, 0, NULL, &outSize1, streamIDs); if (err != noErr) { jack_error("IsDigitalDevice kAudioDevicePropertyStreams list err = %d", err); return false; } AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 }; for (int i = 0; i < stream_count ; i++) { /* Find a stream with a cac3 stream */ int format_num = 0; /* Retrieve all the stream formats supported by each output stream */ err = AudioObjectGetPropertyDataSize(streamIDs[i], &physicalFormatsAddress, 0, NULL, &outSize1); if (err != noErr) { jack_error("IsDigitalDevice kAudioStreamPropertyAvailablePhysicalFormats err = %d", err); return false; } format_num = outSize1 / sizeof(AudioStreamRangedDescription); AudioStreamRangedDescription format_list[format_num]; err = AudioObjectGetPropertyData(streamIDs[i], &physicalFormatsAddress, 0, NULL, &outSize1, format_list); if (err != noErr) { jack_error("IsDigitalDevice could not get the list of streamformats err = %d", err); return false; } /* Check if one of the supported formats is a digital format */ for (int j = 0; j < format_num; j++) { PrintStreamDesc(&format_list[j].mFormat); if (format_list[j].mFormat.mFormatID == 'IAC3' || format_list[j].mFormat.mFormatID == 'iac3' || format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || format_list[j].mFormat.mFormatID == kAudioFormatAC3) { is_digital = true; break; } } } return is_digital; } JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), fAC3Encoder(NULL), fJackInputData(NULL), fDriverOutputData(NULL), fPluginID(0), fState(false), fHogged(false), fIOUsage(1.f), fComputationGrain(-1.f), fClockDriftCompensate(false), fDigitalPlayback(false) {} JackCoreAudioDriver::~JackCoreAudioDriver() { delete fAC3Encoder; } OSStatus JackCoreAudioDriver::DestroyAggregateDevice() { OSStatus osErr = noErr; AudioObjectPropertyAddress pluginAOPA; pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; if (fPluginID > 0) { osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { jack_error("DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); printError(osErr); return osErr; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); if (osErr != noErr) { jack_error("DestroyAggregateDevice : AudioObjectGetPropertyData error"); printError(osErr); return osErr; } } return noErr; } OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) { OSStatus err = noErr; AudioObjectID sub_device[32]; UInt32 outSize = sizeof(sub_device); err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); vector captureDeviceIDArray; jack_log("JackCoreAudioDriver::CreateAggregateDevice : input device %d", captureDeviceID); if (err != noErr) { jack_log("JackCoreAudioDriver::CreateAggregateDevice : input device does not have subdevices"); captureDeviceIDArray.push_back(captureDeviceID); } else { int num_devices = outSize / sizeof(AudioObjectID); jack_log("JackCoreAudioDriver::CreateAggregateDevice : input device has %d subdevices", num_devices); for (int i = 0; i < num_devices; i++) { jack_log("JackCoreAudioDriver::CreateAggregateDevice : input sub_device %d", sub_device[i]); captureDeviceIDArray.push_back(sub_device[i]); } } outSize = sizeof(sub_device); err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); vector playbackDeviceIDArray; jack_log("JackCoreAudioDriver::CreateAggregateDevice : output device %d", playbackDeviceID); if (err != noErr) { jack_log("JackCoreAudioDriver::CreateAggregateDevice : output device does not have subdevices"); playbackDeviceIDArray.push_back(playbackDeviceID); } else { int num_devices = outSize / sizeof(AudioObjectID); jack_log("JackCoreAudioDriver::CreateAggregateDevice : output device has %d subdevices", num_devices); for (int i = 0; i < num_devices; i++) { jack_log("JackCoreAudioDriver::CreateAggregateDevice : output sub_device %d", sub_device[i]); playbackDeviceIDArray.push_back(sub_device[i]); } } return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); } OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) { OSStatus osErr = noErr; UInt32 outSize; Boolean outWritable; // Prepare sub-devices for clock drift compensation // Workaround for bug in the HAL : until 10.6.2 AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; UInt32 theQualifierDataSize = sizeof(AudioObjectID); AudioClassID inClass = kAudioSubDeviceClassID; void* theQualifierData = &inClass; UInt32 subDevicesNum = 0; //--------------------------------------------------------------------------- // Setup SR of both devices otherwise creating AD may fail... //--------------------------------------------------------------------------- UInt32 keptclockdomain = 0; UInt32 clockdomain = 0; outSize = sizeof(UInt32); bool need_clock_drift_compensation = false; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { jack_error("CreateAggregateDeviceAux : cannot set SR of input device"); } else { // Check clock domain osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { jack_error("CreateAggregateDeviceAux : kAudioDevicePropertyClockDomain error"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : input clockdomain = %d", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { jack_error("CreateAggregateDeviceAux : devices do not share the same clock!! clock drift compensation would be needed..."); need_clock_drift_compensation = true; } } } } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { jack_error("CreateAggregateDeviceAux : cannot set SR of output device"); } else { // Check clock domain osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { jack_error("CreateAggregateDeviceAux : kAudioDevicePropertyClockDomain error"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : output clockdomain = %d", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { jack_error("CreateAggregateDeviceAux : devices do not share the same clock!! clock drift compensation would be needed..."); need_clock_drift_compensation = true; } } } } // If no valid clock domain was found, then assume we have to compensate... if (keptclockdomain == 0) { need_clock_drift_compensation = true; } //--------------------------------------------------------------------------- // Start to create a new aggregate by getting the base audio hardware plugin //--------------------------------------------------------------------------- char device_name[256]; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { GetDeviceNameFromID(captureDeviceID[i], device_name); jack_info("Separated input = '%s' ", device_name); } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { GetDeviceNameFromID(playbackDeviceID[i], device_name); jack_info("Separated output = '%s' ", device_name); } osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); if (osErr != noErr) { jack_error("CreateAggregateDeviceAux : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); printError(osErr); return osErr; } AudioValueTranslation pluginAVT; CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); pluginAVT.mInputData = &inBundleRef; pluginAVT.mInputDataSize = sizeof(inBundleRef); pluginAVT.mOutputData = &fPluginID; pluginAVT.mOutputDataSize = sizeof(fPluginID); osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); if (osErr != noErr) { jack_error("CreateAggregateDeviceAux : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); printError(osErr); return osErr; } //------------------------------------------------- // Create a CFDictionary for our aggregate device //------------------------------------------------- CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); // add the name of the device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); // add our choice of UID for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); // add a "private aggregate key" to the dictionary int value = 1; CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); SInt32 system; Gestalt(gestaltSystemVersion, &system); jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : system version = %x limit = %x", system, 0x00001054); // Starting with 10.5.4 systems, the AD can be internal... (better) if (system < 0x00001054) { jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : public aggregate device...."); } else { jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : private aggregate device...."); CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); } // Prepare sub-devices for clock drift compensation CFMutableArrayRef subDevicesArrayClock = NULL; /* if (fClockDriftCompensate) { if (need_clock_drift_compensation) { jack_info("Clock drift compensation activated..."); subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef UID = GetDeviceName(captureDeviceID[i]); if (UID) { CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); //CFRelease(UID); CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); } } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef UID = GetDeviceName(playbackDeviceID[i]); if (UID) { CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); //CFRelease(UID); CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); } } // add sub-device clock array for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); } else { jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); } } */ //------------------------------------------------- // Create a CFMutableArray for our sub-device list //------------------------------------------------- // we need to append the UID for each device to a CFMutableArray, so create one here CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); vector captureDeviceUID; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(captureDeviceID[i]); if (ref == NULL) { return -1; } captureDeviceUID.push_back(ref); // input sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } vector playbackDeviceUID; for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(playbackDeviceID[i]); if (ref == NULL) { return -1; } playbackDeviceUID.push_back(ref); // output sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } //----------------------------------------------------------------------- // Feed the dictionary to the plugin, to create a blank aggregate device //----------------------------------------------------------------------- AudioObjectPropertyAddress pluginAOPA; pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { jack_error("CreateAggregateDeviceAux : AudioObjectGetPropertyDataSize error"); printError(osErr); goto error; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); if (osErr != noErr) { jack_error("CreateAggregateDeviceAux : AudioObjectGetPropertyData error"); printError(osErr); goto error; } // pause for a bit to make sure that everything completed correctly // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //------------------------- // Set the sub-device list //------------------------- pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFMutableArrayRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); if (osErr != noErr) { jack_error("CreateAggregateDeviceAux : AudioObjectSetPropertyData for sub-device list error"); printError(osErr); goto error; } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //----------------------- // Set the master device //----------------------- // set the master device manually (this is the device which will act as the master clock for the aggregate device) // pass in the UID of the device you want to use pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFStringRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &playbackDeviceUID[0]); // First playback is master... if (osErr != noErr) { jack_error("CreateAggregateDeviceAux : AudioObjectSetPropertyData for master device error"); printError(osErr); goto error; } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); // Prepare sub-devices for clock drift compensation // Workaround for bug in the HAL : until 10.6.2 if (fClockDriftCompensate) { if (need_clock_drift_compensation) { jack_info("Clock drift compensation activated..."); // Get the property data size osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); if (osErr != noErr) { jack_error("CreateAggregateDeviceAux kAudioObjectPropertyOwnedObjects error"); printError(osErr); } // Calculate the number of object IDs subDevicesNum = outSize / sizeof(AudioObjectID); jack_info("JackCoreAudioDriver::CreateAggregateDeviceAux clock drift compensation, number of sub-devices = %d", subDevicesNum); AudioObjectID subDevices[subDevicesNum]; outSize = sizeof(subDevices); osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); if (osErr != noErr) { jack_error("CreateAggregateDeviceAux kAudioObjectPropertyOwnedObjects error"); printError(osErr); } // Set kAudioSubDevicePropertyDriftCompensation property... for (UInt32 index = 0; index < subDevicesNum; ++index) { UInt32 theDriftCompensationValue = 1; osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); if (osErr != noErr) { jack_error("CreateAggregateDeviceAux kAudioSubDevicePropertyDriftCompensation error"); printError(osErr); } } } else { jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); } } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //---------- // Clean up //---------- // release the private AD key CFRelease(AggregateDeviceNumberRef); // release the CF objects we have created - we don't need them any more CFRelease(aggDeviceDict); CFRelease(subDevicesArray); if (subDevicesArrayClock) { CFRelease(subDevicesArrayClock); } // release the device UID for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { CFRelease(captureDeviceUID[i]); } for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { CFRelease(playbackDeviceUID[i]); } jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : new aggregate device %ld", *outAggregateDevice); return noErr; error: DestroyAggregateDevice(); return -1; } int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name, jack_nframes_t samplerate, bool ac3_encoding) { capture_driver_name[0] = 0; playback_driver_name[0] = 0; // Duplex if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::SetupDevices : duplex"); // Same device for capture and playback... if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default in/out"); if (GetDefaultDevice(&fDeviceID) != noErr) { jack_error("Cannot open default device"); return -1; } } if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { jack_error("Cannot get device name from device ID"); return -1; } if (fHogged) { if (!TakeHogAux(fDeviceID, false)) { jack_error("Cannot take hog mode"); } if (ac3_encoding) { fDigitalPlayback = IsDigitalDevice(fDeviceID); } } } else { // Creates aggregate device AudioDeviceID captureID = -1; AudioDeviceID playbackID = -1; if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default input"); if (GetDefaultInputDevice(&captureID) != noErr) { jack_error("Cannot open default input device"); return -1; } } if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default output"); if (GetDefaultOutputDevice(&playbackID) != noErr) { jack_error("Cannot open default output device"); return -1; } } if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) { return -1; } GetDeviceNameFromID(captureID, fCaptureUID); GetDeviceNameFromID(playbackID, fPlaybackUID); if (fHogged) { if (!TakeHogAux(captureID, true)) { jack_error("Cannot take hog mode for capture device"); } if (!TakeHogAux(playbackID, false)) { jack_error("Cannot take hog mode for playback device"); } if (ac3_encoding) { fDigitalPlayback = IsDigitalDevice(playbackID); } } } // Capture only } else if (strcmp(capture_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::SetupDevices : capture only"); if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default input"); if (GetDefaultInputDevice(&fDeviceID) != noErr) { jack_error("Cannot open default input device"); return -1; } } if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr) { jack_error("Cannot get device name from device ID"); return -1; } if (fHogged) { if (!TakeHogAux(fDeviceID, true)) { jack_error("Cannot take hog mode for capture device"); } } // Playback only } else if (strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::SetupDevices : playback only"); if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default output"); if (GetDefaultOutputDevice(&fDeviceID) != noErr) { jack_error("Cannot open default output device"); return -1; } } if (GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { jack_error("Cannot get device name from device ID"); return -1; } if (fHogged) { if (!TakeHogAux(fDeviceID, false)) { jack_error("Cannot take hog mode for playback device"); } if (ac3_encoding) { fDigitalPlayback = IsDigitalDevice(fDeviceID); } } // Use default driver in duplex mode } else { jack_log("JackCoreAudioDriver::SetupDevices : default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); // Creates aggregate device AudioDeviceID captureID = -1; AudioDeviceID playbackID = -1; if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default input"); if (GetDefaultInputDevice(&captureID) != noErr) { jack_error("Cannot open default input device"); return -1; } } if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { jack_log("JackCoreAudioDriver::SetupDevices : will take default output"); if (GetDefaultOutputDevice(&playbackID) != noErr) { jack_error("Cannot open default output device"); return -1; } } if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) { return -1; } GetDeviceNameFromID(captureID, fCaptureUID); GetDeviceNameFromID(playbackID, fPlaybackUID); if (fHogged) { if (!TakeHogAux(captureID, true)) { jack_error("Cannot take hog mode for capture device"); } if (!TakeHogAux(playbackID, false)) { jack_error("Cannot take hog mode for playback device"); } if (ac3_encoding) { fDigitalPlayback = IsDigitalDevice(playbackID); } } } } return 0; } /* Return the max possible input channels in in_maxChannels and output channels in out_maxChannels. */ int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchannels, int& outchannels, int& in_maxChannels, int& out_maxChannels, bool strict) { OSStatus err = noErr; jack_log("JackCoreAudioDriver::SetupChannels : fDeviceID = %d", fDeviceID); if (capturing) { err = GetTotalChannels(fDeviceID, in_maxChannels, true); if (err != noErr) { jack_error("SetupChannels : cannot get input channel number"); printError(err); return -1; } else { jack_log("JackCoreAudioDriver::SetupChannels : max input channels : %d", in_maxChannels); } } if (playing) { err = GetTotalChannels(fDeviceID, out_maxChannels, false); if (err != noErr) { jack_error("Cannot get output channel number"); printError(err); return -1; } else { jack_log("JackCoreAudioDriver::SetupChannels : max output channels : %d", out_maxChannels); } } if (inchannels > in_maxChannels) { jack_error("This device hasn't required input channels inchannels = %d in_maxChannels = %d", inchannels, in_maxChannels); if (strict) { return -1; } } if (outchannels > out_maxChannels) { jack_error("This device hasn't required output channels outchannels = %d out_maxChannels = %d", outchannels, out_maxChannels); if (strict) { return -1; } } if (inchannels == -1) { jack_log("JackCoreAudioDriver::SetupChannels : setup max in channels = %d", in_maxChannels); inchannels = in_maxChannels; } if (outchannels == -1) { jack_log("JackCoreAudioDriver::SetupChannels : setup max out channels = %d", out_maxChannels); outchannels = out_maxChannels; } return 0; } int JackCoreAudioDriver::SetupBufferSize(jack_nframes_t buffer_size) { // Setting buffer size OSStatus err = noErr; UInt32 tmp_buffer_size = buffer_size; UInt32 outSize = sizeof(UInt32); err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &tmp_buffer_size); if (err != noErr) { jack_error("Cannot get buffer size %ld", buffer_size); printError(err); return -1; } else { jack_log("JackCoreAudioDriver::SetupBufferSize : current buffer size = %ld", tmp_buffer_size); } // If needed, set new buffer size if (buffer_size != tmp_buffer_size) { tmp_buffer_size = buffer_size; // To get BS change notification err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyBufferFrameSize"); printError(err); return -1; } // Waiting for BS change notification int count = 0; fState = false; err = AudioDeviceSetProperty(fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, outSize, &tmp_buffer_size); if (err != noErr) { jack_error("SetupBufferSize : cannot set buffer size = %ld", tmp_buffer_size); printError(err); goto error; } while (!fState && count++ < WAIT_NOTIFICATION_COUNTER) { usleep(100000); jack_log("JackCoreAudioDriver::SetupBufferSize : wait count = %d", count); } if (count >= WAIT_NOTIFICATION_COUNTER) { jack_error("Did not get buffer size notification..."); goto error; } // Check new buffer size outSize = sizeof(UInt32); err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &tmp_buffer_size); if (err != noErr) { jack_error("Cannot get current buffer size"); printError(err); } else { jack_log("JackCoreAudioDriver::SetupBufferSize : checked buffer size = %ld", tmp_buffer_size); } // Remove BS change notification AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback); } return 0; error: // Remove BS change notification AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback); return -1; } int JackCoreAudioDriver::SetupSampleRate(jack_nframes_t sample_rate) { return SetupSampleRateAux(fDeviceID, sample_rate); } int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t sample_rate) { OSStatus err = noErr; UInt32 outSize; Float64 tmp_sample_rate; // Get sample rate outSize = sizeof(Float64); err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &tmp_sample_rate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); return -1; } else { jack_log("JackCoreAudioDriver::SetupSampleRateAux : current sample rate = %f", tmp_sample_rate); } // If needed, set new sample rate if (sample_rate != (jack_nframes_t)tmp_sample_rate) { tmp_sample_rate = (Float64)sample_rate; // To get SR change notification err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate"); printError(err); return -1; } // Waiting for SR change notification int count = 0; fState = false; err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &tmp_sample_rate); if (err != noErr) { jack_error("Cannot set sample rate = %ld", sample_rate); printError(err); goto error; } while (!fState && count++ < WAIT_NOTIFICATION_COUNTER) { usleep(100000); jack_log("JackCoreAudioDriver::SetupSampleRateAux : wait count = %d", count); } if (count >= WAIT_NOTIFICATION_COUNTER) { jack_error("Did not get sample rate notification..."); goto error; } // Check new sample rate outSize = sizeof(Float64); err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &tmp_sample_rate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); } else { jack_log("JackCoreAudioDriver::SetupSampleRateAux : checked sample rate = %f", tmp_sample_rate); } // Remove SR change notification AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); } return 0; error: // Remove SR change notification AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); return -1; } int JackCoreAudioDriver::OpenAUHAL(bool capturing, bool playing, int inchannels, int outchannels, int in_maxChannels, int out_maxChannels, const vector& chan_in_list, const vector& chan_out_list, jack_nframes_t buffer_size, jack_nframes_t sample_rate) { ComponentResult err1; UInt32 enableIO; AudioStreamBasicDescription srcFormat, dstFormat; AudioDeviceID currAudioDeviceID; UInt32 size; jack_log("JackCoreAudioDriver::OpenAUHAL : capturing = %d playing = %d inchannels = %d outchannels = %d in_maxChannels = %d out_maxChannels = %d chan_in_list = %d chan_out_list = %d", capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, chan_in_list.size(), chan_out_list.size()); if (inchannels == 0 && outchannels == 0) { jack_error("No input and output channels..."); return -1; } // AUHAL #ifdef MAC_OS_X_VERSION_10_5 ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; Component HALOutput = FindNextComponent(NULL, &cd); err1 = OpenAComponent(HALOutput, &fAUHAL); if (err1 != noErr) { jack_error("Error calling OpenAComponent"); printError(err1); goto error; } #else AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd); err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL); if (err1 != noErr) { jack_error("Error calling AudioComponentInstanceNew"); printError(err1); goto error; } #endif err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { jack_error("Cannot initialize AUHAL unit"); printError(err1); goto error; } // Start I/O if (capturing && inchannels > 0) { enableIO = 1; jack_log("JackCoreAudioDriver::OpenAUHAL : setup AUHAL input on"); } else { enableIO = 0; jack_log("JackCoreAudioDriver::OpenAUHAL : setup AUHAL input off"); } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); printError(err1); goto error; } if (playing && outchannels > 0) { enableIO = 1; jack_log("JackCoreAudioDriver::OpenAUHAL : setup AUHAL output on"); } else { enableIO = 0; jack_log("JackCoreAudioDriver::OpenAUHAL : setup AUHAL output off"); } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output"); printError(err1); goto error; } size = sizeof(AudioDeviceID); err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); goto error; } else { jack_log("JackCoreAudioDriver::OpenAUHAL : AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); } // Setup up choosen device, in both input and output cases err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID, sizeof(AudioDeviceID)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); goto error; } // Set buffer size if (capturing && inchannels > 0) { err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); goto error; } } if (playing && outchannels > 0) { err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&buffer_size, sizeof(UInt32)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); goto error; } } // Setup input channel map if (capturing && inchannels > 0 && inchannels <= in_maxChannels) { SInt32 chanArr[in_maxChannels]; for (int i = 0; i < in_maxChannels; i++) { chanArr[i] = -1; } // Explicit mapping if (chan_in_list.size() > 0) { for (uint i = 0; i < chan_in_list.size(); i++) { int chan = chan_in_list[i]; if (chan < in_maxChannels) { // The wanted JACK input index for the 'chan' channel value chanArr[chan] = i; jack_info("Input channel = %d ==> JACK input port = %d", chan, i); } else { jack_info("Error input channel number is incorrect : %d", chan); goto error; } } } else { for (int i = 0; i < inchannels; i++) { chanArr[i] = i; jack_info("Input channel = %d ==> JACK input port = %d", chanArr[i], i); } } AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_maxChannels); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for input"); printError(err1); goto error; } } // Setup output channel map if (playing && outchannels > 0 && outchannels <= out_maxChannels) { SInt32 chanArr[out_maxChannels]; for (int i = 0; i < out_maxChannels; i++) { chanArr[i] = -1; } // Explicit mapping if (chan_out_list.size() > 0) { for (uint i = 0; i < chan_out_list.size(); i++) { int chan = chan_out_list[i]; if (chan < out_maxChannels) { // The wanted JACK output index for the 'chan' channel value chanArr[chan] = i; jack_info("JACK output port = %d ==> output channel = %d", i, chan); } else { jack_info("Error output channel number is incorrect : %d", chan); goto error; } } } else { for (int i = 0; i < outchannels; i++) { chanArr[i] = i; jack_info("JACK output port = %d ==> output channel = %d", i, chanArr[i]); } } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_maxChannels); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for output"); printError(err1); goto error; } } // Setup stream converters if (capturing && inchannels > 0) { size = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); printError(err1); goto error; } PrintStreamDesc(&srcFormat); jack_log("JackCoreAudioDriver::OpenAUHAL : setup AUHAL input stream converter SR = %ld", sample_rate); srcFormat.mSampleRate = sample_rate; srcFormat.mFormatID = kAudioFormatLinearPCM; srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; srcFormat.mBytesPerPacket = sizeof(jack_default_audio_sample_t); srcFormat.mFramesPerPacket = 1; srcFormat.mBytesPerFrame = sizeof(jack_default_audio_sample_t); srcFormat.mChannelsPerFrame = inchannels; srcFormat.mBitsPerChannel = 32; PrintStreamDesc(&srcFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); printError(err1); goto error; } } if (playing && outchannels > 0) { size = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); printError(err1); goto error; } PrintStreamDesc(&dstFormat); jack_log("JackCoreAudioDriver::OpenAUHAL : setup AUHAL output stream converter SR = %ld", sample_rate); dstFormat.mSampleRate = sample_rate; dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; dstFormat.mBytesPerPacket = sizeof(jack_default_audio_sample_t); dstFormat.mFramesPerPacket = 1; dstFormat.mBytesPerFrame = sizeof(jack_default_audio_sample_t); dstFormat.mChannelsPerFrame = outchannels; dstFormat.mBitsPerChannel = 32; PrintStreamDesc(&dstFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); printError(err1); goto error; } } // Setup callbacks if (inchannels > 0 && outchannels == 0) { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1"); printError(err1); goto error; } } else { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0"); printError(err1); goto error; } } return 0; error: CloseAUHAL(); return -1; } int JackCoreAudioDriver::SetupBuffers(int inchannels) { // Prepare buffers fJackInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); fJackInputData->mNumberBuffers = inchannels; for (int i = 0; i < inchannels; i++) { fJackInputData->mBuffers[i].mNumberChannels = 1; fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(jack_default_audio_sample_t); } return 0; } void JackCoreAudioDriver::DisposeBuffers() { if (fJackInputData) { free(fJackInputData); fJackInputData = 0; } } void JackCoreAudioDriver::CloseAUHAL() { AudioOutputUnitStop(fAUHAL); AudioUnitUninitialize(fAUHAL); CloseComponent(fAUHAL); } int JackCoreAudioDriver::AddListeners() { OSStatus err = noErr; // Add listeners err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload"); printError(err); return -1; } err = AudioHardwareAddPropertyListener(kAudioHardwarePropertyDevices, AudioHardwareNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioHardwareAddPropertyListener with kAudioHardwarePropertyDevices"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyDeviceIsRunning"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsAlive, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyDeviceIsAlive"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceHasChanged, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyDeviceHasChanged"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyStreamConfiguration"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyStreamConfiguration"); printError(err); return -1; } if (!fEngineControl->fSyncMode && fIOUsage != 1.f) { UInt32 outSize = sizeof(float); err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyIOCycleUsage, outSize, &fIOUsage); if (err != noErr) { jack_error("Error calling AudioDeviceSetProperty kAudioDevicePropertyIOCycleUsage"); printError(err); } } return 0; } void JackCoreAudioDriver::RemoveListeners() { AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback); AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDevices, AudioHardwareNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsAlive, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceHasChanged, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback); } int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, jack_nframes_t sample_rate, bool capturing, bool playing, int inchannels, int outchannels, const char* chan_in_list, const char* chan_out_list, bool monitor, const char* capture_driver_uid, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency, int async_output_latency, int computation_grain, bool hogged, bool clock_drift, bool ac3_encoding, int ac3_bitrate, bool ac3_lfe) { int in_maxChannels = 0; int out_maxChannels = 0; char capture_driver_name[256]; char playback_driver_name[256]; fCaptureLatency = capture_latency; fPlaybackLatency = playback_latency; fIOUsage = float(async_output_latency) / 100.f; fComputationGrain = float(computation_grain) / 100.f; fHogged = hogged; fClockDriftCompensate = clock_drift; SInt32 major; SInt32 minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); vector parsed_chan_in_list; vector parsed_chan_out_list; // Starting with 10.6 systems, the HAL notification thread is created internally if (major == 10 && minor >= 6) { CFRunLoopRef theRunLoop = NULL; AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); if (osErr != noErr) { jack_error("Open kAudioHardwarePropertyRunLoop error"); printError(osErr); } } if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, sample_rate, ac3_encoding) < 0) { goto error; } // Generic JackAudioDriver Open if (JackAudioDriver::Open(buffer_size, sample_rate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) { goto error; } if (SetupChannels(capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, !ac3_encoding) < 0) { goto error; } ParseChannelList(chan_in_list, parsed_chan_in_list, in_maxChannels); if (parsed_chan_in_list.size() > 0) { jack_info("Explicit input channel list size = %d", parsed_chan_in_list.size()); inchannels = parsed_chan_in_list.size(); } ParseChannelList(chan_out_list, parsed_chan_out_list, out_maxChannels); if (parsed_chan_out_list.size() > 0) { jack_info("Explicit output channel list size = %d", parsed_chan_out_list.size()); outchannels = parsed_chan_out_list.size(); } if (SetupBufferSize(buffer_size) < 0) { goto error; } if (SetupSampleRate(sample_rate) < 0) { goto error; } if (ac3_encoding) { if (!fDigitalPlayback) { jack_error("AC3 encoding can only be used with a digital device"); goto error; } JackAC3EncoderParams params; memset(¶ms, 0, sizeof(JackAC3EncoderParams)); params.bitrate = ac3_bitrate; params.channels = outchannels; params.sample_rate = sample_rate; params.lfe = ac3_lfe; fAC3Encoder = new JackAC3Encoder(params); if (!fAC3Encoder || !fAC3Encoder->Init(sample_rate)) { jack_error("Cannot allocate or init AC3 encoder"); goto error; } // Setup AC3 channel number fPlaybackChannels = outchannels; if (ac3_lfe) { fPlaybackChannels++; } if (fPlaybackChannels < 2 || fPlaybackChannels > 6) { jack_error("AC3 encoder channels must be between 2 and 6"); goto error; } // Force real output channel number to 2 outchannels = out_maxChannels = 2; } else { fPlaybackChannels = outchannels; } // Core driver may have changed the in/out values fCaptureChannels = inchannels; if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, parsed_chan_in_list, parsed_chan_out_list, buffer_size, sample_rate) < 0) { goto error; } if (capturing && inchannels > 0) { if (SetupBuffers(inchannels) < 0) { goto error; } } if (AddListeners() < 0) { goto error; } return noErr; error: Close(); return -1; } int JackCoreAudioDriver::Close() { jack_log("JackCoreAudioDriver::Close"); // Generic audio driver close int res = JackAudioDriver::Close(); RemoveListeners(); DisposeBuffers(); CloseAUHAL(); DestroyAggregateDevice(); return res; } void JackCoreAudioDriver::UpdateLatencies() { UInt32 size; OSStatus err; jack_latency_range_t input_range; jack_latency_range_t output_range; jack_latency_range_t monitor_range; // Get Input latency size = sizeof(UInt32); UInt32 value1 = 0; UInt32 value2 = 0; err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1); if (err != noErr) { jack_error("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); } err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2); if (err != noErr) { jack_error("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); } input_range.min = input_range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; // Get input stream latencies vector input_latencies; err = GetStreamLatencies(fDeviceID, true, input_latencies); for (int i = 0; i < fCaptureChannels; i++) { if (err != noErr) { input_range.min += input_latencies[i]; input_range.max += input_latencies[i]; } fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); } // Get Output latency size = sizeof(UInt32); value1 = 0; value2 = 0; err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1); if (err != noErr) { jack_error("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); } err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2); if (err != noErr) { jack_error("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); } // Get output stream latencies vector output_latencies; err = GetStreamLatencies(fDeviceID, false, output_latencies); // Add more latency if "async" mode is used... output_range.min = output_range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency; for (int i = 0; i < fPlaybackChannels; i++) { if (err != noErr) { output_range.min += output_latencies[i]; output_range.max += output_latencies[i]; } fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); // Monitor port if (fWithMonitorPorts) { monitor_range.min = monitor_range.max = fEngineControl->fBufferSize; fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range); } } } int JackCoreAudioDriver::Attach() { OSStatus err; JackPort* port; jack_port_id_t port_index; UInt32 size; Boolean isWritable; char channel_name[64]; char name[REAL_JACK_PORT_NAME_SIZE+1]; char alias[REAL_JACK_PORT_NAME_SIZE+1]; jack_log("JackCoreAudioDriver::Attach : fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (int i = 0; i < fCaptureChannels; i++) { err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, &isWritable); if (err != noErr) { jack_log("JackCoreAudioDriver::Attach : AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error"); } if (err == noErr && size > 0) { err = AudioDeviceGetProperty(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, channel_name); if (err != noErr) { jack_log("JackCoreAudioDriver::Attach : AudioDeviceGetProperty kAudioDevicePropertyChannelName error"); } snprintf(alias, sizeof(alias), "%s:%s:out_%s%u", fAliasName, fCaptureDriverName, channel_name, i + 1); } else { snprintf(alias, sizeof(alias), "%s:%s:out%u", fAliasName, fCaptureDriverName, i + 1); } snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("Cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fCapturePortList[i] = port_index; } for (int i = 0; i < fPlaybackChannels; i++) { err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable); if (err != noErr) { jack_log("JackCoreAudioDriver::Attach : AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error"); } if (err == noErr && size > 0) { err = AudioDeviceGetProperty(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, channel_name); if (err != noErr) { jack_log("JackCoreAudioDriver::Attach : AudioDeviceGetProperty kAudioDevicePropertyChannelName error"); } snprintf(alias, sizeof(alias), "%s:%s:in_%s%u", fAliasName, fPlaybackDriverName, channel_name, i + 1); } else { snprintf(alias, sizeof(alias), "%s:%s:in%u", fAliasName, fPlaybackDriverName, i + 1); } snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("Cannot register port for %s", name); return -1; } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); fPlaybackPortList[i] = port_index; // Monitor ports if (fWithMonitorPorts) { jack_log("JackCoreAudioDriver::Attach : create monitor port"); snprintf(name, sizeof(name), "%s:monitor_%u", fClientControl.fName, i + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("Cannot register monitor port for %s", name); return -1; } else { fMonitorPortList[i] = port_index; } } } if (fAC3Encoder) { // Setup specific AC3 channels names for (int i = 0; i < fPlaybackChannels; i++) { fAC3Encoder->GetChannelName("coreaudio", "", alias, i); port = fGraphManager->GetPort(fPlaybackPortList[i]); port->SetAlias(alias); } } UpdateLatencies(); // Input buffers do no change : prepare them only once for (int i = 0; i < fCaptureChannels; i++) { fJackInputData->mBuffers[i].mData = GetInputBuffer(i); } return 0; } int JackCoreAudioDriver::Start() { jack_log("JackCoreAudioDriver::Start"); if (JackAudioDriver::Start() == 0) { // Waiting for Render callback to be called (= driver has started) fState = false; int count = 0; if (AudioOutputUnitStart(fAUHAL) == noErr) { while (!fState && count++ < WAIT_COUNTER) { usleep(100000); jack_log("JackCoreAudioDriver::Start : wait count = %d", count); } if (count < WAIT_COUNTER) { jack_info("CoreAudio driver is running..."); return 0; } jack_error("CoreAudio driver cannot start..."); } JackAudioDriver::Stop(); } return -1; } int JackCoreAudioDriver::Stop() { jack_log("JackCoreAudioDriver::Stop"); int res = (AudioOutputUnitStop(fAUHAL) == noErr) ? 0 : -1; if (JackAudioDriver::Stop() < 0) { res = -1; } return res; } int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) { if (SetupBufferSize(buffer_size) < 0) { return -1; } JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails // CoreAudio specific UpdateLatencies(); // Input buffers do no change : prepare them only once for (int i = 0; i < fCaptureChannels; i++) { fJackInputData->mBuffers[i].mNumberChannels = 1; fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(jack_default_audio_sample_t); fJackInputData->mBuffers[i].mData = GetInputBuffer(i); } return 0; } bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) { pid_t hog_pid; UInt32 propSize = sizeof(hog_pid); OSStatus err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyHogMode, &propSize, &hog_pid); if (err) { jack_error("Cannot read hog state..."); printError(err); } jack_log("JackCoreAudioDriver::TakeHogAux : deviceID = %d", deviceID); if (hog_pid != getpid()) { hog_pid = getpid(); err = AudioDeviceSetProperty(deviceID, 0, 0, isInput, kAudioDevicePropertyHogMode, propSize, &hog_pid); if (err != noErr) { jack_error("Can't hog device = %d because it's being hogged by another program or cannot be hogged", deviceID); return false; } } return true; } bool JackCoreAudioDriver::TakeHog() { OSStatus err = noErr; AudioObjectID sub_device[32]; UInt32 outSize = sizeof(sub_device); err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); if (err != noErr) { jack_log("JackCoreAudioDriver::TakeHog : device does not have subdevices"); return TakeHogAux(fDeviceID, true); } else { int num_devices = outSize / sizeof(AudioObjectID); jack_log("JackCoreAudioDriver::TakeHog : device does has %d subdevices", num_devices); for (int i = 0; i < num_devices; i++) { if (!TakeHogAux(sub_device[i], true)) { return false; } } return true; } } bool JackCoreAudioDriver::IsAggregateDevice(AudioDeviceID device) { UInt32 deviceType, outSize = sizeof(UInt32); OSStatus err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyTransportType, &outSize, &deviceType); if (err != noErr) { jack_log("JackCoreAudioDriver::IsAggregateDevice kAudioDevicePropertyTransportType error"); return false; } else { return (deviceType == kAudioDeviceTransportTypeAggregate); } } } // end of namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("coreaudio", JackDriverMaster, "Apple CoreAudio API based audio backend", &filler); value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "channels", 'c', JackDriverParamInt, &value, NULL, "Maximum number of channels", "Maximum number of channels. If -1, max possible number of channels will be used"); jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", "Maximum number of input channels. If -1, max possible number of input channels will be used"); jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used"); value.str[0] = 0; jack_driver_descriptor_add_parameter(desc, &filler, "input-list", 'n', JackDriverParamString, &value, NULL, "Input channel list for channel mapping", "List of input channel number to be opened (syntax like : \"0 3 2\")"); jack_driver_descriptor_add_parameter(desc, &filler, "output-list", 'N', JackDriverParamString, &value, NULL, "Output channel list for channel mapping", "List of output channel number to be opened (syntax like : \"0 3 2\")"); value.str[0] = 0; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input CoreAudio device name", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Output CoreAudio device name", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "monitor", 'm', JackDriverParamBool, &value, NULL, "Provide monitor ports for the output", NULL); #ifndef __ppc__ value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "AC3-encoding", 'a', JackDriverParamBool, &value, NULL, "AC3 multi-channels encoding", NULL); value.i = 448; jack_driver_descriptor_add_parameter(desc, &filler, "AC3-bitrate", 'b', JackDriverParamUInt, &value, NULL, "AC3 bitrate", NULL); value.i = 0; jack_driver_descriptor_add_parameter(desc, &filler, "AC3-LFE", 'f', JackDriverParamBool, &value, NULL, "AC3 LFE channel", NULL); #endif value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports", NULL); value.ui = 44100U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = 256U; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.str[0] = 0; jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "CoreAudio device name", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "input-latency", 'I', JackDriverParamUInt, &value, NULL, "Extra input latency (frames)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "output-latency", 'O', JackDriverParamUInt, &value, NULL, "Extra output latency (frames)", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "list-devices", 'l', JackDriverParamBool, &value, NULL, "Display available CoreAudio devices", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "hog", 'H', JackDriverParamBool, &value, NULL, "Take exclusive access of the audio device", NULL); value.ui = 100; jack_driver_descriptor_add_parameter(desc, &filler, "async-latency", 'L', JackDriverParamUInt, &value, NULL, "Extra output latency in asynchronous mode (percent)", NULL); value.ui = 100; jack_driver_descriptor_add_parameter(desc, &filler, "grain", 'G', JackDriverParamUInt, &value, NULL, "Computation grain in RT thread (percent)", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "clock-drift", 's', JackDriverParamBool, &value, NULL, "Clock drift compensation", "Whether to compensate clock drift in dynamically created aggregate device"); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t srate = 44100; jack_nframes_t frames_per_interrupt = 256; bool capture = false; bool playback = false; int chan_in = -1; // Default: if not explicitely set, then max possible will be used... int chan_out = -1; // Default: if not explicitely set, then max possible will be used... const char* chan_in_list = ""; const char* chan_out_list = ""; bool monitor = false; const char* capture_driver_uid = ""; const char* playback_driver_uid = ""; const JSList *node; const jack_driver_param_t *param; jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; int async_output_latency = 100; int computation_grain = -1; bool hogged = false; bool clock_drift = false; bool ac3_encoding = false; int ac3_bitrate = 448; bool ac3_lfe = false; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'd': capture_driver_uid = param->value.str; playback_driver_uid = param->value.str; break; case 'D': capture = true; playback = true; break; case 'c': chan_in = chan_out = param->value.i; break; case 'i': chan_in = param->value.i; break; case 'o': chan_out = param->value.i; break; case 'n': chan_in_list = param->value.str; break; case 'N': chan_out_list = param->value.str; break; case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { capture_driver_uid = param->value.str; } break; case 'P': playback = true; if (strcmp(param->value.str, "none") != 0) { playback_driver_uid = param->value.str; } break; case 'm': monitor = param->value.i; break; #ifndef __ppc__ case 'a': ac3_encoding = param->value.i; break; case 'b': ac3_bitrate = param->value.i; break; case 'f': ac3_lfe = param->value.i; break; #endif case 'r': srate = param->value.ui; break; case 'p': frames_per_interrupt = (unsigned int)param->value.ui; break; case 'I': systemic_input_latency = param->value.ui; break; case 'O': systemic_output_latency = param->value.ui; break; case 'l': Jack::DisplayDeviceNames(); // Stops the server in this case return NULL; case 'H': hogged = true; break; case 'L': async_output_latency = param->value.ui; break; case 'G': computation_grain = param->value.ui; break; case 's': clock_drift = true; break; } } /* duplex is the default */ if (!capture && !playback) { capture = true; playback = true; } if (strcmp(chan_in_list, "") != 0 && chan_in >= 0) { printf("Input channel list and in channels are both specified, input channel list will take over...\n"); } if (strcmp(chan_out_list, "") != 0 && chan_out >= 0) { printf("Output channel list and out channels are both specified, output channel list will take over...\n"); } Jack::JackCoreAudioDriver* driver = new Jack::JackCoreAudioDriver("system", "coreaudio", engine, table); if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, chan_in_list, chan_out_list, monitor, capture_driver_uid, playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain, hogged, clock_drift, ac3_encoding, ac3_bitrate, ac3_lfe) == 0) { return driver; } else { delete driver; return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/macosx/coreaudio/JackCoreAudioAdapter.h0000644000000000000000000001450713214314510020730 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreAudioAdapter__ #define __JackCoreAudioAdapter__ #include "JackAudioAdapterInterface.h" #include "jack.h" #include "jslist.h" #include #include #include #include using namespace std; namespace Jack { typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01) #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) #define WAIT_COUNTER 60 /*! \brief Audio adapter using CoreAudio API. */ class JackCoreAudioAdapter : public JackAudioAdapterInterface { private: AudioUnit fAUHAL; AudioBufferList* fInputData; char fCaptureUID[256]; char fPlaybackUID[256]; bool fCapturing; bool fPlaying; AudioDeviceID fDeviceID; // Used "duplex" device AudioObjectID fPluginID; // Used for aggregate device vector fInputLatencies; vector fOutputLatencies; bool fState; AudioUnitRenderActionFlags* fActionFags; AudioTimeStamp* fCurrentTime; bool fClockDriftCompensate; static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); static OSStatus AudioHardwareNotificationCallback(AudioHardwarePropertyID inPropertyID,void* inClientData); static OSStatus SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData); static OSStatus DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData); OSStatus GetDefaultDevice(AudioDeviceID* id); OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); OSStatus GetDeviceIDFromUID(const char* UID, AudioDeviceID* id); OSStatus GetDefaultInputDevice(AudioDeviceID* id); OSStatus GetDefaultOutputDevice(AudioDeviceID* id); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); AudioDeviceID GetDeviceIDFromName(const char* name); // Setup OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus DestroyAggregateDevice(); bool IsAggregateDevice(AudioDeviceID device); int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name, jack_nframes_t samplerate); int SetupChannels(bool capturing, bool playing, int& inchannels, int& outchannels, int& in_nChannels, int& out_nChannels, bool strict); int OpenAUHAL(bool capturing, bool playing, int inchannels, int outchannels, int in_nChannels, int out_nChannels, jack_nframes_t buffer_size, jack_nframes_t samplerate); int SetupBufferSize(jack_nframes_t buffer_size); int SetupSampleRate(jack_nframes_t samplerate); int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate); int SetupBuffers(int inchannels); void DisposeBuffers(); void CloseAUHAL(); int AddListeners(); void RemoveListeners(); int GetLatency(int port_index, bool input); OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector& latencies); OSStatus Render(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData); public: JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackCoreAudioAdapter() {} virtual int Open(); virtual int Close(); virtual int SetSampleRate(jack_nframes_t sample_rate); virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int GetInputLatency(int port_index); virtual int GetOutputLatency(int port_index); }; } // end of namepace #ifdef __cplusplus extern "C" { #endif #include "JackCompilerDeps.h" #include "driver_interface.h" SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor(); #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/macosx/coreaudio/JackCoreAudioAdapter.mm0000644000000000000000000020400613214314510021105 0ustar rootroot/* Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackCoreAudioAdapter.h" #include "JackError.h" #include #include namespace Jack { static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) { jack_log("- - - - - - - - - - - - - - - - - - - -"); jack_log(" Sample Rate:%f", inDesc->mSampleRate); jack_log(" Format ID:%.*s", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); jack_log(" Format Flags:%lX", inDesc->mFormatFlags); jack_log(" Bytes per Packet:%ld", inDesc->mBytesPerPacket); jack_log(" Frames per Packet:%ld", inDesc->mFramesPerPacket); jack_log(" Bytes per Frame:%ld", inDesc->mBytesPerFrame); jack_log(" Channels per Frame:%ld", inDesc->mChannelsPerFrame); jack_log(" Bits per Channel:%ld", inDesc->mBitsPerChannel); jack_log("- - - - - - - - - - - - - - - - - - - -"); } static OSStatus DisplayDeviceNames() { UInt32 size; Boolean isWritable; int i, deviceNum; OSStatus err; CFStringRef UIname; err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); if (err != noErr) { return err; } deviceNum = size / sizeof(AudioDeviceID); AudioDeviceID devices[deviceNum]; err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); if (err != noErr) { return err; } for (i = 0; i < deviceNum; i++) { char device_name[256]; char internal_name[256]; size = sizeof(CFStringRef); UIname = NULL; err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); if (err == noErr) { CFStringGetCString(UIname, internal_name, 256, CFStringGetSystemEncoding()); } else { goto error; } size = 256; err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name); if (err != noErr) { return err; } jack_info("Device name = \'%s\', internal_name = \'%s\' (to be used as -C, -P, or -d parameter)", device_name, internal_name); } return noErr; error: if (UIname != NULL) { CFRelease(UIname); } return err; } static void printError(OSStatus err) { switch (err) { case kAudioHardwareNoError: jack_log("error code : kAudioHardwareNoError"); break; case kAudioConverterErr_FormatNotSupported: jack_log("error code : kAudioConverterErr_FormatNotSupported"); break; case kAudioConverterErr_OperationNotSupported: jack_log("error code : kAudioConverterErr_OperationNotSupported"); break; case kAudioConverterErr_PropertyNotSupported: jack_log("error code : kAudioConverterErr_PropertyNotSupported"); break; case kAudioConverterErr_InvalidInputSize: jack_log("error code : kAudioConverterErr_InvalidInputSize"); break; case kAudioConverterErr_InvalidOutputSize: jack_log("error code : kAudioConverterErr_InvalidOutputSize"); break; case kAudioConverterErr_UnspecifiedError: jack_log("error code : kAudioConverterErr_UnspecifiedError"); break; case kAudioConverterErr_BadPropertySizeError: jack_log("error code : kAudioConverterErr_BadPropertySizeError"); break; case kAudioConverterErr_RequiresPacketDescriptionsError: jack_log("error code : kAudioConverterErr_RequiresPacketDescriptionsError"); break; case kAudioConverterErr_InputSampleRateOutOfRange: jack_log("error code : kAudioConverterErr_InputSampleRateOutOfRange"); break; case kAudioConverterErr_OutputSampleRateOutOfRange: jack_log("error code : kAudioConverterErr_OutputSampleRateOutOfRange"); break; case kAudioHardwareNotRunningError: jack_log("error code : kAudioHardwareNotRunningError"); break; case kAudioHardwareUnknownPropertyError: jack_log("error code : kAudioHardwareUnknownPropertyError"); break; case kAudioHardwareIllegalOperationError: jack_log("error code : kAudioHardwareIllegalOperationError"); break; case kAudioHardwareBadDeviceError: jack_log("error code : kAudioHardwareBadDeviceError"); break; case kAudioHardwareBadStreamError: jack_log("error code : kAudioHardwareBadStreamError"); break; case kAudioDeviceUnsupportedFormatError: jack_log("error code : kAudioDeviceUnsupportedFormatError"); break; case kAudioDevicePermissionsError: jack_log("error code : kAudioDevicePermissionsError"); break; case kAudioHardwareBadObjectError: jack_log("error code : kAudioHardwareBadObjectError"); break; case kAudioHardwareUnsupportedOperationError: jack_log("error code : kAudioHardwareUnsupportedOperationError"); break; default: jack_log("error code : unknown"); break; } } OSStatus JackCoreAudioAdapter::AudioHardwareNotificationCallback(AudioHardwarePropertyID inPropertyID, void* inClientData) { JackCoreAudioAdapter* driver = (JackCoreAudioAdapter*)inClientData; switch (inPropertyID) { case kAudioHardwarePropertyDevices: { jack_log("JackCoreAudioAdapter::AudioHardwareNotificationCallback kAudioHardwarePropertyDevices"); DisplayDeviceNames(); break; } } return noErr; } OSStatus JackCoreAudioAdapter::SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { JackCoreAudioAdapter* driver = static_cast(inClientData); switch (inPropertyID) { case kAudioDevicePropertyNominalSampleRate: { jack_log("JackCoreAudioAdapter::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); driver->fState = true; break; } } return noErr; } // A better implementation would try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) OSStatus JackCoreAudioAdapter::DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { switch (inPropertyID) { case kAudioDeviceProcessorOverload: { jack_error("JackCoreAudioAdapter::DeviceNotificationCallback kAudioDeviceProcessorOverload"); break; } case kAudioDevicePropertyStreamConfiguration: { jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration"); return kAudioHardwareUnsupportedOperationError; } case kAudioDevicePropertyNominalSampleRate: { jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate"); return kAudioHardwareUnsupportedOperationError; } } return noErr; } int JackCoreAudioAdapter::AddListeners() { OSStatus err = noErr; // Add listeners err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload"); printError(err); return -1; } err = AudioHardwareAddPropertyListener(kAudioHardwarePropertyDevices, AudioHardwareNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioHardwareAddPropertyListener with kAudioHardwarePropertyDevices"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyDeviceIsRunning"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyStreamConfiguration"); printError(err); return -1; } err = AudioDeviceAddPropertyListener(fDeviceID, 0, false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyStreamConfiguration"); printError(err); return -1; } return 0; } void JackCoreAudioAdapter::RemoveListeners() { AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback); AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDevices, AudioHardwareNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback); } OSStatus JackCoreAudioAdapter::Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { return static_cast(inRefCon)->Render(ioActionFlags, inTimeStamp, inNumberFrames, ioData); } OSStatus JackCoreAudioAdapter::Render(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData) { OSStatus err = AudioUnitRender(fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, fInputData); if (err == noErr) { jack_default_audio_sample_t* inputBuffer[fCaptureChannels]; jack_default_audio_sample_t* outputBuffer[fPlaybackChannels]; for (int i = 0; i < fCaptureChannels; i++) { inputBuffer[i] = (jack_default_audio_sample_t*)fInputData->mBuffers[i].mData; } for (int i = 0; i < fPlaybackChannels; i++) { outputBuffer[i] = (jack_default_audio_sample_t*)ioData->mBuffers[i].mData; } PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, inNumberFrames); return noErr; } else { return err; } } JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) :JackAudioAdapterInterface(buffer_size, sample_rate), fInputData(0), fCapturing(false), fPlaying(false), fState(false) { const JSList* node; const jack_driver_param_t* param; int in_nChannels = 0; int out_nChannels = 0; char captureName[256]; char playbackName[256]; fCaptureUID[0] = 0; fPlaybackUID[0] = 0; fClockDriftCompensate = false; // Default values fCaptureChannels = -1; fPlaybackChannels = -1; SInt32 major; SInt32 minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); // Starting with 10.6 systems, the HAL notification thread is created internally if (major == 10 && minor >= 6) { CFRunLoopRef theRunLoop = NULL; AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus theError = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); if (theError != noErr) { jack_error("JackCoreAudioAdapter::Open kAudioHardwarePropertyRunLoop error"); } } for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'i': fCaptureChannels = param->value.ui; break; case 'o': fPlaybackChannels = param->value.ui; break; case 'C': fCapturing = true; strncpy(fCaptureUID, param->value.str, 256); break; case 'P': fPlaying = true; strncpy(fPlaybackUID, param->value.str, 256); break; case 'd': strncpy(fCaptureUID, param->value.str, 256); strncpy(fPlaybackUID, param->value.str, 256); break; case 'D': fCapturing = fPlaying = true; break; case 'r': SetAdaptedSampleRate(param->value.ui); break; case 'p': SetAdaptedBufferSize(param->value.ui); break; case 'l': DisplayDeviceNames(); break; case 'q': fQuality = param->value.ui; break; case 'g': fRingbufferCurSize = param->value.ui; fAdaptative = false; break; case 's': fClockDriftCompensate = true; break; } } /* duplex is the default */ if (!fCapturing && !fPlaying) { fCapturing = true; fPlaying = true; } if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0) { throw std::bad_alloc(); } if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0) { throw std::bad_alloc(); } if (SetupBufferSize(fAdaptedBufferSize) < 0) { throw std::bad_alloc(); } if (SetupSampleRate(fAdaptedSampleRate) < 0) { throw std::bad_alloc(); } if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate) < 0) { throw std::bad_alloc(); } if (fCapturing && fCaptureChannels > 0) { if (SetupBuffers(fCaptureChannels) < 0) { throw std::bad_alloc(); } } if (AddListeners() < 0) { throw std::bad_alloc(); } GetStreamLatencies(fDeviceID, true, fInputLatencies); GetStreamLatencies(fDeviceID, false, fOutputLatencies); } OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id) { OSStatus res; UInt32 theSize = sizeof(UInt32); AudioDeviceID inDefault; AudioDeviceID outDefault; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) { return res; } if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) { return res; } jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); // Get the device only if default input and output are the same if (inDefault != outDefault) { jack_error("Default input and output devices are not the same !!"); return kAudioHardwareBadDeviceError; } else if (inDefault == 0) { jack_error("Default input and output devices are null !!"); return kAudioHardwareBadDeviceError; } else { *id = inDefault; return noErr; } } OSStatus JackCoreAudioAdapter::GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput) { OSStatus err = noErr; UInt32 outSize; Boolean outWritable; channelCount = 0; err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); if (err == noErr) { AudioBufferList bufferList[outSize]; err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); if (err == noErr) { for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) { channelCount += bufferList->mBuffers[i].mNumberChannels; } } } return err; } OSStatus JackCoreAudioAdapter::GetDeviceIDFromUID(const char* UID, AudioDeviceID* id) { UInt32 size = sizeof(AudioValueTranslation); CFStringRef inIUD = CFStringCreateWithCString(NULL, UID, CFStringGetSystemEncoding()); AudioValueTranslation value = { &inIUD, sizeof(CFStringRef), id, sizeof(AudioDeviceID) }; if (inIUD == NULL) { return kAudioHardwareUnspecifiedError; } else { OSStatus res = AudioHardwareGetProperty(kAudioHardwarePropertyDeviceForUID, &size, &value); CFRelease(inIUD); jack_log("GetDeviceIDFromUID %s %ld", UID, *id); return (*id == kAudioDeviceUnknown) ? kAudioHardwareBadDeviceError : res; } } OSStatus JackCoreAudioAdapter::GetDefaultInputDevice(AudioDeviceID* id) { OSStatus res; UInt32 theSize = sizeof(UInt32); AudioDeviceID inDefault; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) { return res; } if (inDefault == 0) { jack_error("Error: default input device is 0, please select a correct one !!"); return -1; } jack_log("GetDefaultInputDevice: input = %ld ", inDefault); *id = inDefault; return noErr; } OSStatus JackCoreAudioAdapter::GetDefaultOutputDevice(AudioDeviceID* id) { OSStatus res; UInt32 theSize = sizeof(UInt32); AudioDeviceID outDefault; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) { return res; } if (outDefault == 0) { jack_error("Error: default output device is 0, please select a correct one !!"); return -1; } jack_log("GetDefaultOutputDevice: output = %ld", outDefault); *id = outDefault; return noErr; } OSStatus JackCoreAudioAdapter::GetDeviceNameFromID(AudioDeviceID id, char* name) { UInt32 size = 256; return AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, name); } AudioDeviceID JackCoreAudioAdapter::GetDeviceIDFromName(const char* name) { UInt32 size; Boolean isWritable; int i, deviceNum; OSStatus err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); if (err != noErr) { return -1; } deviceNum = size / sizeof(AudioDeviceID); AudioDeviceID devices[deviceNum]; err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); if (err != noErr) { return err; } for (i = 0; i < deviceNum; i++) { char device_name[256]; size = 256; err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name); if (err != noErr) { return -1; } else if (strcmp(device_name, name) == 0) { return devices[i]; } } return -1; } // Setup int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name, jack_nframes_t samplerate) { capture_driver_name[0] = 0; playback_driver_name[0] = 0; // Duplex if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::Open duplex"); // Same device for capture and playback... if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { jack_log("Will take default in/out"); if (GetDefaultDevice(&fDeviceID) != noErr) { jack_error("Cannot open default device"); return -1; } } if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { jack_error("Cannot get device name from device ID"); return -1; } } else { // Creates aggregate device AudioDeviceID captureID, playbackID; if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { jack_log("Will take default input"); if (GetDefaultInputDevice(&captureID) != noErr) { jack_error("Cannot open default input device"); return -1; } } if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { jack_log("Will take default output"); if (GetDefaultOutputDevice(&playbackID) != noErr) { jack_error("Cannot open default output device"); return -1; } } if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) { return -1; } } // Capture only } else if (strcmp(capture_driver_uid, "") != 0) { jack_log("JackCoreAudioAdapter::Open capture only"); if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) { if (GetDefaultInputDevice(&fDeviceID) != noErr) { jack_error("Cannot open default input device"); return -1; } } if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr) { jack_error("Cannot get device name from device ID"); return -1; } // Playback only } else if (strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioAdapter::Open playback only"); if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { if (GetDefaultOutputDevice(&fDeviceID) != noErr) { jack_error("Cannot open default output device"); return -1; } } if (GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { jack_error("Cannot get device name from device ID"); return -1; } // Use default driver in duplex mode } else { jack_log("JackCoreAudioAdapter::Open default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); // Creates aggregate device AudioDeviceID captureID = -1, playbackID = -1; if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { jack_log("Will take default input"); if (GetDefaultInputDevice(&captureID) != noErr) { jack_error("Cannot open default input device"); goto built_in; } } if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { jack_log("Will take default output"); if (GetDefaultOutputDevice(&playbackID) != noErr) { jack_error("Cannot open default output device"); goto built_in; } } if (captureID > 0 && playbackID > 0) { if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) { goto built_in; } } else { jack_error("Cannot use default input/output"); goto built_in; } } } return 0; built_in: // Aggregate built-in input and output AudioDeviceID captureID = GetDeviceIDFromName("Built-in Input"); AudioDeviceID playbackID = GetDeviceIDFromName("Built-in Output"); if (captureID > 0 && playbackID > 0) { if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) { return -1; } } else { jack_error("Cannot aggregate built-in input and output"); return -1; } return 0; } int JackCoreAudioAdapter::SetupChannels(bool capturing, bool playing, int& inchannels, int& outchannels, int& in_nChannels, int& out_nChannels, bool strict) { OSStatus err = noErr; if (capturing) { err = GetTotalChannels(fDeviceID, in_nChannels, true); if (err != noErr) { jack_error("Cannot get input channel number"); printError(err); return -1; } else { jack_log("Max input channels : %d", in_nChannels); } } if (playing) { err = GetTotalChannels(fDeviceID, out_nChannels, false); if (err != noErr) { jack_error("Cannot get output channel number"); printError(err); return -1; } else { jack_log("Max output channels : %d", out_nChannels); } } if (inchannels > in_nChannels) { jack_error("This device hasn't required input channels inchannels = %ld in_nChannels = %ld", inchannels, in_nChannels); if (strict) { return -1; } } if (outchannels > out_nChannels) { jack_error("This device hasn't required output channels outchannels = %ld out_nChannels = %ld", outchannels, out_nChannels); if (strict) { return -1; } } if (inchannels == -1) { jack_log("Setup max in channels = %ld", in_nChannels); inchannels = in_nChannels; } if (outchannels == -1) { jack_log("Setup max out channels = %ld", out_nChannels); outchannels = out_nChannels; } return 0; } int JackCoreAudioAdapter::SetupBufferSize(jack_nframes_t buffer_size) { // Setting buffer size UInt32 outSize = sizeof(UInt32); OSStatus err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); if (err != noErr) { jack_error("Cannot set buffer size %ld", buffer_size); printError(err); return -1; } return 0; } int JackCoreAudioAdapter::SetupSampleRate(jack_nframes_t samplerate) { return SetupSampleRateAux(fDeviceID, samplerate); } int JackCoreAudioAdapter::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate) { OSStatus err = noErr; UInt32 outSize; Float64 sampleRate; // Get sample rate outSize = sizeof(Float64); err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); return -1; } else { jack_log("Current sample rate = %f", sampleRate); } // If needed, set new sample rate if (samplerate != (jack_nframes_t)sampleRate) { sampleRate = (Float64)samplerate; // To get SR change notification err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate"); printError(err); return -1; } err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); if (err != noErr) { jack_error("Cannot set sample rate = %ld", samplerate); printError(err); return -1; } // Waiting for SR change notification int count = 0; while (!fState && count++ < WAIT_COUNTER) { usleep(100000); jack_log("Wait count = %d", count); } // Remove SR change notification AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); } return 0; } int JackCoreAudioAdapter::SetupBuffers(int inchannels) { jack_log("JackCoreAudioAdapter::SetupBuffers: input = %ld", inchannels); // Prepare buffers fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); fInputData->mNumberBuffers = inchannels; for (int i = 0; i < fCaptureChannels; i++) { fInputData->mBuffers[i].mNumberChannels = 1; fInputData->mBuffers[i].mDataByteSize = fAdaptedBufferSize * sizeof(jack_default_audio_sample_t); fInputData->mBuffers[i].mData = malloc(fAdaptedBufferSize * sizeof(jack_default_audio_sample_t)); } return 0; } void JackCoreAudioAdapter::DisposeBuffers() { if (fInputData) { for (int i = 0; i < fCaptureChannels; i++) { free(fInputData->mBuffers[i].mData); } free(fInputData); fInputData = 0; } } int JackCoreAudioAdapter::OpenAUHAL(bool capturing, bool playing, int inchannels, int outchannels, int in_nChannels, int out_nChannels, jack_nframes_t buffer_size, jack_nframes_t samplerate) { ComponentResult err1; UInt32 enableIO; AudioStreamBasicDescription srcFormat, dstFormat; AudioDeviceID currAudioDeviceID; UInt32 size; jack_log("OpenAUHAL capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); if (inchannels == 0 && outchannels == 0) { jack_error("No input and output channels..."); return -1; } // AUHAL #ifdef MAC_OS_X_VERSION_10_5 ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; Component HALOutput = FindNextComponent(NULL, &cd); err1 = OpenAComponent(HALOutput, &fAUHAL); if (err1 != noErr) { jack_error("Error calling OpenAComponent"); printError(err1); goto error; } #else AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd); err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL); if (err1 != noErr) { jack_error("Error calling AudioComponentInstanceNew"); printError(err1); goto error; } #endif err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { jack_error("Cannot initialize AUHAL unit"); printError(err1); goto error; } // Start I/O if (capturing && inchannels > 0) { enableIO = 1; jack_log("Setup AUHAL input on"); } else { enableIO = 0; jack_log("Setup AUHAL input off"); } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); printError(err1); goto error; } if (playing && outchannels > 0) { enableIO = 1; jack_log("Setup AUHAL output on"); } else { enableIO = 0; jack_log("Setup AUHAL output off"); } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); printError(err1); goto error; } size = sizeof(AudioDeviceID); err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); goto error; } else { jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); } // Setup up choosen device, in both input and output cases err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID, sizeof(AudioDeviceID)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); goto error; } // Set buffer size if (capturing && inchannels > 0) { err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); goto error; } } if (playing && outchannels > 0) { err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&buffer_size, sizeof(UInt32)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); goto error; } } // Setup channel map if (capturing && inchannels > 0 && inchannels <= in_nChannels) { SInt32 chanArr[in_nChannels]; for (int i = 0; i < in_nChannels; i++) { chanArr[i] = -1; } for (int i = 0; i < inchannels; i++) { chanArr[i] = i; } AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1"); printError(err1); goto error; } } if (playing && outchannels > 0 && outchannels <= out_nChannels) { SInt32 chanArr[out_nChannels]; for (int i = 0; i < out_nChannels; i++) { chanArr[i] = -1; } for (int i = 0; i < outchannels; i++) { chanArr[i] = i; } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0"); printError(err1); goto error; } } // Setup stream converters if (capturing && inchannels > 0) { size = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); printError(err1); goto error; } PrintStreamDesc(&srcFormat); jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); srcFormat.mSampleRate = samplerate; srcFormat.mFormatID = kAudioFormatLinearPCM; srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; srcFormat.mBytesPerPacket = sizeof(jack_default_audio_sample_t); srcFormat.mFramesPerPacket = 1; srcFormat.mBytesPerFrame = sizeof(jack_default_audio_sample_t); srcFormat.mChannelsPerFrame = inchannels; srcFormat.mBitsPerChannel = 32; PrintStreamDesc(&srcFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); printError(err1); goto error; } } if (playing && outchannels > 0) { size = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); printError(err1); goto error; } PrintStreamDesc(&dstFormat); jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); dstFormat.mSampleRate = samplerate; dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; dstFormat.mBytesPerPacket = sizeof(jack_default_audio_sample_t); dstFormat.mFramesPerPacket = 1; dstFormat.mBytesPerFrame = sizeof(jack_default_audio_sample_t); dstFormat.mChannelsPerFrame = outchannels; dstFormat.mBitsPerChannel = 32; PrintStreamDesc(&dstFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); printError(err1); goto error; } } // Setup callbacks if (inchannels > 0 && outchannels == 0) { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1"); printError(err1); goto error; } } else { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0"); printError(err1); goto error; } } return 0; error: CloseAUHAL(); return -1; } OSStatus JackCoreAudioAdapter::DestroyAggregateDevice() { OSStatus osErr = noErr; AudioObjectPropertyAddress pluginAOPA; pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); printError(osErr); return osErr; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::DestroyAggregateDevice : AudioObjectGetPropertyData error"); printError(osErr); return osErr; } return noErr; } static CFStringRef GetDeviceName(AudioDeviceID id) { UInt32 size = sizeof(CFStringRef); CFStringRef UIname; OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); return (err == noErr) ? UIname : NULL; } OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) { OSStatus err = noErr; AudioObjectID sub_device[32]; UInt32 outSize = sizeof(sub_device); err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); vector captureDeviceIDArray; if (err != noErr) { jack_log("Input device does not have subdevices"); captureDeviceIDArray.push_back(captureDeviceID); } else { int num_devices = outSize / sizeof(AudioObjectID); jack_log("Input device has %d subdevices", num_devices); for (int i = 0; i < num_devices; i++) { captureDeviceIDArray.push_back(sub_device[i]); } } outSize = sizeof(sub_device); err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); vector playbackDeviceIDArray; if (err != noErr) { jack_log("Output device does not have subdevices"); playbackDeviceIDArray.push_back(playbackDeviceID); } else { int num_devices = outSize / sizeof(AudioObjectID); jack_log("Output device has %d subdevices", num_devices); for (int i = 0; i < num_devices; i++) { playbackDeviceIDArray.push_back(sub_device[i]); } } return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); } OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) { OSStatus osErr = noErr; UInt32 outSize; Boolean outWritable; // Prepare sub-devices for clock drift compensation // Workaround for bug in the HAL : until 10.6.2 AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; UInt32 theQualifierDataSize = sizeof(AudioObjectID); AudioClassID inClass = kAudioSubDeviceClassID; void* theQualifierData = &inClass; UInt32 subDevicesNum = 0; //--------------------------------------------------------------------------- // Setup SR of both devices otherwise creating AD may fail... //--------------------------------------------------------------------------- UInt32 keptclockdomain = 0; UInt32 clockdomain = 0; outSize = sizeof(UInt32); bool need_clock_drift_compensation = false; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot set SR of input device"); } else { // Check clock domain osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; jack_log("JackCoreAudioAdapter::CreateAggregateDevice : input clockdomain = %d", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); need_clock_drift_compensation = true; } } } } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot set SR of output device"); } else { // Check clock domain osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; jack_log("JackCoreAudioAdapter::CreateAggregateDevice : output clockdomain = %d", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); need_clock_drift_compensation = true; } } } } // If no valid clock domain was found, then assume we have to compensate... if (keptclockdomain == 0) { need_clock_drift_compensation = true; } //--------------------------------------------------------------------------- // Start to create a new aggregate by getting the base audio hardware plugin //--------------------------------------------------------------------------- char device_name[256]; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { GetDeviceNameFromID(captureDeviceID[i], device_name); jack_info("Separated input = '%s' ", device_name); } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { GetDeviceNameFromID(playbackDeviceID[i], device_name); jack_info("Separated output = '%s' ", device_name); } osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); printError(osErr); return osErr; } AudioValueTranslation pluginAVT; CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); pluginAVT.mInputData = &inBundleRef; pluginAVT.mInputDataSize = sizeof(inBundleRef); pluginAVT.mOutputData = &fPluginID; pluginAVT.mOutputDataSize = sizeof(fPluginID); osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); printError(osErr); return osErr; } //------------------------------------------------- // Create a CFDictionary for our aggregate device //------------------------------------------------- CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); // add the name of the device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); // add our choice of UID for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); // add a "private aggregate key" to the dictionary int value = 1; CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); SInt32 system; Gestalt(gestaltSystemVersion, &system); jack_log("JackCoreAudioAdapter::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); // Starting with 10.5.4 systems, the AD can be internal... (better) if (system < 0x00001054) { jack_log("JackCoreAudioAdapter::CreateAggregateDevice : public aggregate device...."); } else { jack_log("JackCoreAudioAdapter::CreateAggregateDevice : private aggregate device...."); CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); } // Prepare sub-devices for clock drift compensation CFMutableArrayRef subDevicesArrayClock = NULL; /* if (fClockDriftCompensate) { if (need_clock_drift_compensation) { jack_info("Clock drift compensation activated..."); subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef UID = GetDeviceName(captureDeviceID[i]); if (UID) { CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); //CFRelease(UID); CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); } } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef UID = GetDeviceName(playbackDeviceID[i]); if (UID) { CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); //CFRelease(UID); CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); } } // add sub-device clock array for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); } else { jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); } } */ //------------------------------------------------- // Create a CFMutableArray for our sub-device list //------------------------------------------------- // we need to append the UID for each device to a CFMutableArray, so create one here CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); vector captureDeviceUID; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(captureDeviceID[i]); if (ref == NULL) { return -1; } captureDeviceUID.push_back(ref); // input sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } vector playbackDeviceUID; for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(playbackDeviceID[i]); if (ref == NULL) { return -1; } playbackDeviceUID.push_back(ref); // output sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } //----------------------------------------------------------------------- // Feed the dictionary to the plugin, to create a blank aggregate device //----------------------------------------------------------------------- AudioObjectPropertyAddress pluginAOPA; pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); printError(osErr); goto error; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectGetPropertyData error"); printError(osErr); goto error; } // pause for a bit to make sure that everything completed correctly // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //------------------------- // Set the sub-device list //------------------------- pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFMutableArrayRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); printError(osErr); goto error; } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //----------------------- // Set the master device //----------------------- // set the master device manually (this is the device which will act as the master clock for the aggregate device) // pass in the UID of the device you want to use pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFStringRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &playbackDeviceUID[0]); // First playback is master... if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); printError(osErr); goto error; } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); // Prepare sub-devices for clock drift compensation // Workaround for bug in the HAL : until 10.6.2 if (fClockDriftCompensate) { if (need_clock_drift_compensation) { jack_info("Clock drift compensation activated..."); // Get the property data size osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); printError(osErr); } // Calculate the number of object IDs subDevicesNum = outSize / sizeof(AudioObjectID); jack_info("JackCoreAudioAdapter::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); AudioObjectID subDevices[subDevicesNum]; outSize = sizeof(subDevices); osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); printError(osErr); } // Set kAudioSubDevicePropertyDriftCompensation property... for (UInt32 index = 0; index < subDevicesNum; ++index) { UInt32 theDriftCompensationValue = 1; osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); if (osErr != noErr) { jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); printError(osErr); } } } else { jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); } } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //---------- // Clean up //---------- // release the private AD key CFRelease(AggregateDeviceNumberRef); // release the CF objects we have created - we don't need them any more CFRelease(aggDeviceDict); CFRelease(subDevicesArray); if (subDevicesArrayClock) { CFRelease(subDevicesArrayClock); } // release the device UID for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { CFRelease(captureDeviceUID[i]); } for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { CFRelease(playbackDeviceUID[i]); } jack_log("New aggregate device %ld", *outAggregateDevice); return noErr; error: DestroyAggregateDevice(); return -1; } bool JackCoreAudioAdapter::IsAggregateDevice(AudioDeviceID device) { OSStatus err = noErr; AudioObjectID sub_device[32]; UInt32 outSize = sizeof(sub_device); err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); if (err != noErr) { jack_log("Device does not have subdevices"); return false; } else { int num_devices = outSize / sizeof(AudioObjectID); jack_log("Device does has %d subdevices", num_devices); return true; } } void JackCoreAudioAdapter::CloseAUHAL() { AudioUnitUninitialize(fAUHAL); CloseComponent(fAUHAL); } int JackCoreAudioAdapter::Open() { return (AudioOutputUnitStart(fAUHAL) != noErr) ? -1 : 0; } int JackCoreAudioAdapter::Close() { #ifdef JACK_MONITOR fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif AudioOutputUnitStop(fAUHAL); DisposeBuffers(); CloseAUHAL(); RemoveListeners(); if (fPluginID > 0) { DestroyAggregateDevice(); } return 0; } int JackCoreAudioAdapter::SetSampleRate(jack_nframes_t sample_rate) { JackAudioAdapterInterface::SetHostSampleRate(sample_rate); Close(); return Open(); } int JackCoreAudioAdapter::SetBufferSize(jack_nframes_t buffer_size) { JackAudioAdapterInterface::SetHostBufferSize(buffer_size); Close(); return Open(); } OSStatus JackCoreAudioAdapter::GetStreamLatencies(AudioDeviceID device, bool isInput, vector& latencies) { OSStatus err = noErr; UInt32 outSize1, outSize2, outSize3; Boolean outWritable; err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, &outWritable); if (err == noErr) { int stream_count = outSize1 / sizeof(UInt32); AudioStreamID streamIDs[stream_count]; AudioBufferList bufferList[stream_count]; UInt32 streamLatency; outSize2 = sizeof(UInt32); err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, streamIDs); if (err != noErr) { jack_error("GetStreamLatencies kAudioDevicePropertyStreams err = %d", err); return err; } err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, &outWritable); if (err != noErr) { jack_error("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err); return err; } for (int i = 0; i < stream_count; i++) { err = AudioStreamGetProperty(streamIDs[i], 0, kAudioStreamPropertyLatency, &outSize2, &streamLatency); if (err != noErr) { jack_error("GetStreamLatencies kAudioStreamPropertyLatency err = %d", err); return err; } err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, bufferList); if (err != noErr) { jack_error("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err); return err; } // Push 'channel' time the stream latency for (uint k = 0; k < bufferList->mBuffers[i].mNumberChannels; k++) { latencies.push_back(streamLatency); } } } return err; } int JackCoreAudioAdapter::GetLatency(int port_index, bool input) { UInt32 size = sizeof(UInt32); UInt32 value1 = 0; UInt32 value2 = 0; OSStatus err = AudioDeviceGetProperty(fDeviceID, 0, input, kAudioDevicePropertyLatency, &size, &value1); if (err != noErr) { jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); } err = AudioDeviceGetProperty(fDeviceID, 0, input, kAudioDevicePropertySafetyOffset, &size, &value2); if (err != noErr) { jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); } // TODO : add stream latency return value1 + value2 + fAdaptedBufferSize; } int JackCoreAudioAdapter::GetInputLatency(int port_index) { if (port_index < int(fInputLatencies.size())) { return GetLatency(port_index, true) + fInputLatencies[port_index]; } else { // No stream latency return GetLatency(port_index, true); } } int JackCoreAudioAdapter::GetOutputLatency(int port_index) { if (port_index < int(fOutputLatencies.size())) { return GetLatency(port_index, false) + fOutputLatencies[port_index]; } else { // No stream latency return GetLatency(port_index, false); } } } // namespace #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler); value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", "Maximum number of input channels. If -1, max possible number of input channels will be used"); jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used"); value.str[0] = 0; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input CoreAudio device name", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Output CoreAudio device name", NULL); value.ui = 44100U; jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = 512U; jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports", NULL); value.str[0] = 0; jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "CoreAudio device name", NULL); value.i = true; jack_driver_descriptor_add_parameter(desc, &filler, "list-devices", 'l', JackDriverParamBool, &value, NULL, "Display available CoreAudio devices", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL); value.ui = 32768; jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)"); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "clock-drift", 's', JackDriverParamBool, &value, NULL, "Clock drift compensation", "Whether to compensate clock drift in dynamically created aggregate device"); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "auto-connect", 'c', JackDriverParamBool, &value, NULL, "Auto connect audioadapter to system ports", NULL); return desc; } #ifdef __cplusplus } #endif 1.9.12~dfsg/macosx/coreaudio/TiPhoneCoreAudioRenderer.mm0000644000000000000000000003735113214314510022000 0ustar rootroot/* Copyright (C) 2010 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TiPhoneCoreAudioRenderer.h" static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) { printf("- - - - - - - - - - - - - - - - - - - -\n"); printf(" Sample Rate:%f\n", inDesc->mSampleRate); printf(" Format ID:%.*s\n", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); printf(" Format Flags:%lX\n", inDesc->mFormatFlags); printf(" Bytes per Packet:%ld\n", inDesc->mBytesPerPacket); printf(" Frames per Packet:%ld\n", inDesc->mFramesPerPacket); printf(" Bytes per Frame:%ld\n", inDesc->mBytesPerFrame); printf(" Channels per Frame:%ld\n", inDesc->mChannelsPerFrame); printf(" Bits per Channel:%ld\n", inDesc->mBitsPerChannel); printf("- - - - - - - - - - - - - - - - - - - -\n"); } static void printError(OSStatus err) { switch (err) { case kAudioConverterErr_FormatNotSupported: printf("error code : kAudioConverterErr_FormatNotSupported\n"); break; case kAudioConverterErr_OperationNotSupported: printf("error code : kAudioConverterErr_OperationNotSupported\n"); break; case kAudioConverterErr_PropertyNotSupported: printf("error code : kAudioConverterErr_PropertyNotSupported\n"); break; case kAudioConverterErr_InvalidInputSize: printf("error code : kAudioConverterErr_InvalidInputSize\n"); break; case kAudioConverterErr_InvalidOutputSize: printf("error code : kAudioConverterErr_InvalidOutputSize\n"); break; case kAudioConverterErr_UnspecifiedError: printf("error code : kAudioConverterErr_UnspecifiedError\n"); break; case kAudioConverterErr_BadPropertySizeError: printf("error code : kAudioConverterErr_BadPropertySizeError\n"); break; case kAudioConverterErr_RequiresPacketDescriptionsError: printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n"); break; case kAudioConverterErr_InputSampleRateOutOfRange: printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n"); break; case kAudioConverterErr_OutputSampleRateOutOfRange: printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n"); break; default: printf("error code : unknown\n"); break; } } OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32, UInt32 inNumberFrames, AudioBufferList *ioData) { TiPhoneCoreAudioRendererPtr renderer = (TiPhoneCoreAudioRendererPtr)inRefCon; AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fCAInputData); float coef = float(LONG_MAX); float inv_coef = 1.f/float(LONG_MAX); for (int chan = 0; chan < renderer->fDevNumInChans; chan++) { for (int frame = 0; frame < inNumberFrames; frame++) { renderer->fInChannel[chan][frame] = float(((int*)renderer->fCAInputData->mBuffers[chan].mData)[frame]) * inv_coef; } } renderer->PerformAudioCallback((int)inNumberFrames); for (int chan = 0; chan < renderer->fDevNumOutChans; chan++) { for (int frame = 0; frame < inNumberFrames; frame++) { ((int*)ioData->mBuffers[chan].mData)[frame] = int(renderer->fOutChannel[chan][frame] * coef); } } return 0; } void TiPhoneCoreAudioRenderer::InterruptionListener(void *inClientData, UInt32 inInterruption) { TiPhoneCoreAudioRenderer *obj = (TiPhoneCoreAudioRenderer*)inClientData; printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); if (inInterruption == kAudioSessionEndInterruption) { // make sure we are again the active session AudioSessionSetActive(true); AudioOutputUnitStart(obj->fAUHAL); } if (inInterruption == kAudioSessionBeginInterruption) { AudioOutputUnitStop(obj->fAUHAL); } } int TiPhoneCoreAudioRenderer::Open(int bufferSize, int samplerate) { OSStatus err1; UInt32 outSize; UInt32 enableIO; AudioStreamBasicDescription srcFormat, dstFormat; printf("Open fDevNumInChans = %ld fDevNumOutChans = %ld bufferSize = %ld samplerate = %ld\n", fDevNumInChans, fDevNumOutChans, bufferSize, samplerate); // Initialize and configure the audio session err1 = AudioSessionInitialize(NULL, NULL, InterruptionListener, this); if (err1 != noErr) { printf("Couldn't initialize audio session\n"); printError(err1); return OPEN_ERR; } err1 = AudioSessionSetActive(true); if (err1 != noErr) { printf("Couldn't set audio session active\n"); printError(err1); return OPEN_ERR; } UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; err1 = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); if (err1 != noErr) { printf("Couldn't set audio category\n"); printError(err1); return OPEN_ERR; } //err1 = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self), "couldn't set property listener"); Float64 hwSampleRate; outSize = sizeof(hwSampleRate); err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &outSize, &hwSampleRate); if (err1 != noErr) { printf("Couldn't get hw sample rate\n"); printError(err1); return OPEN_ERR; } else { printf("Get hw sample rate %f\n", hwSampleRate); } Float32 hwBufferSize; outSize = sizeof(hwBufferSize); err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &outSize, &hwBufferSize); if (err1 != noErr) { printf("Couldn't get hw buffer duration\n"); printError(err1); return OPEN_ERR; } else { printf("Get hw buffer duration %f\n", hwBufferSize); } UInt32 hwInput; outSize = sizeof(hwInput); err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &outSize, &hwInput); if (err1 != noErr) { printf("Couldn't get hw input channels\n"); printError(err1); return OPEN_ERR; } else { printf("Get hw input channels %d\n", hwInput); } UInt32 hwOutput; outSize = sizeof(hwOutput); err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &outSize, &hwOutput); if (err1 != noErr) { printf("Couldn't get hw output channels\n"); printError(err1); return OPEN_ERR; } else { printf("Get hw output channels %d\n", hwOutput); } Float32 preferredBufferSize = float(bufferSize) / float(samplerate); printf("preferredBufferSize %f \n", preferredBufferSize); err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize); if (err1 != noErr) { printf("Couldn't set i/o buffer duration\n"); printError(err1); return OPEN_ERR; } Float64 preferredSamplerate = float(samplerate); err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(preferredSamplerate), &preferredSamplerate); if (err1 != noErr) { printf("Couldn't set i/o sample rate\n"); printError(err1); return OPEN_ERR; } // AUHAL AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple, 0, 0}; AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd); err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL); if (err1 != noErr) { printf("Error calling OpenAComponent\n"); printError(err1); goto error; } enableIO = 1; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n"); printError(err1); goto error; } enableIO = 1; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n"); printError(err1); goto error; } UInt32 maxFPS; outSize = sizeof(maxFPS); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFPS, &outSize); if (err1 != noErr) { printf("Couldn't get kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } else { printf("Get kAudioUnitProperty_MaximumFramesPerSlice %d\n", maxFPS); } err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { printf("Cannot initialize AUHAL unit\n"); printError(err1); goto error; } // Setting format if (fDevNumInChans > 0) { outSize = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize); if (err1 != noErr) { printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } PrintStreamDesc(&srcFormat); srcFormat.mFormatID = kAudioFormatLinearPCM; srcFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; srcFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); srcFormat.mFramesPerPacket = 1; srcFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); srcFormat.mChannelsPerFrame = fDevNumInChans; srcFormat.mBitsPerChannel = 32; PrintStreamDesc(&srcFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } } if (fDevNumOutChans > 0) { outSize = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize); if (err1 != noErr) { printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); printError(err1); } PrintStreamDesc(&dstFormat); dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; dstFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); dstFormat.mFramesPerPacket = 1; dstFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); dstFormat.mChannelsPerFrame = fDevNumOutChans; dstFormat.mBitsPerChannel = 32; PrintStreamDesc(&dstFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); printError(err1); } } if (fDevNumInChans > 0 && fDevNumOutChans == 0) { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n"); printError(err1); goto error; } } else { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n"); printError(err1); goto error; } } // Prepare buffers fCAInputData = (AudioBufferList*)malloc(sizeof(UInt32) + fDevNumInChans * sizeof(AudioBuffer)); fCAInputData->mNumberBuffers = fDevNumInChans; for (int i = 0; i < fDevNumInChans; i++) { fCAInputData->mBuffers[i].mNumberChannels = 1; fCAInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(int); fCAInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(int)); } /* // Add listeners err1 = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload"); printError(err); return -1; } */ return NO_ERR; error: AudioUnitUninitialize(fAUHAL); AudioComponentInstanceDispose(fAUHAL); return OPEN_ERR; } int TiPhoneCoreAudioRenderer::Close() { AudioUnitUninitialize(fAUHAL); AudioComponentInstanceDispose(fAUHAL); if (fCAInputData) { // Free buffers and list for (int i = 0; i < fDevNumInChans; i++) { free(fCAInputData->mBuffers[i].mData); } free(fCAInputData); } return NO_ERR; } int TiPhoneCoreAudioRenderer::Start() { AudioSessionSetActive(true); OSStatus err = AudioOutputUnitStart(fAUHAL); if (err != noErr) { printf("Error while opening device : device open error \n"); return OPEN_ERR; } else { return NO_ERR; } } int TiPhoneCoreAudioRenderer::Stop() { OSStatus err = AudioOutputUnitStop(fAUHAL); if (err != noErr) { printf("Error while closing device : device close error \n"); return OPEN_ERR; } else { return NO_ERR; } } 1.9.12~dfsg/macosx/coreaudio/TiPhoneCoreAudioRenderer.h0000644000000000000000000000670413214314510021614 0ustar rootroot/* Copyright (C) 2010 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __TiPhoneCoreAudioRenderer__ #define __TiPhoneCoreAudioRenderer__ #include #include #include #define MAX_CHANNELS 256 #define OPEN_ERR -1 #define NO_ERR 0 typedef void (*AudioCallback) (int frames, float** inputs, float** outputs, void* arg); class TiPhoneCoreAudioRenderer { private: AudioUnit fAUHAL; AudioCallback fAudioCallback; void* fCallbackArg; int fDevNumInChans; int fDevNumOutChans; AudioBufferList* fCAInputData; float* fInChannel[MAX_CHANNELS]; float* fOutChannel[MAX_CHANNELS]; static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); static void InterruptionListener(void *inClientData, UInt32 inInterruption); public: TiPhoneCoreAudioRenderer(int input, int output) :fAudioCallback(NULL), fCallbackArg(NULL), fDevNumInChans(input), fDevNumOutChans(output), fCAInputData(NULL) { memset(fInChannel, 0, sizeof(float*) * MAX_CHANNELS); memset(fOutChannel, 0, sizeof(float*) * MAX_CHANNELS); for (int i = 0; i < fDevNumInChans; i++) { fInChannel[i] = new float[8192]; } for (int i = 0; i < fDevNumOutChans; i++) { fOutChannel[i] = new float[8192]; } } virtual ~TiPhoneCoreAudioRenderer() { for (int i = 0; i < fDevNumInChans; i++) { delete[] fInChannel[i]; } for (int i = 0; i < fDevNumOutChans; i++) { delete[] fOutChannel[i]; } if (fCAInputData) { for (int i = 0; i < fDevNumInChans; i++) { free(fCAInputData->mBuffers[i].mData); } free(fCAInputData); } } int Open(int bufferSize, int sampleRate); int Close(); int Start(); int Stop(); void SetAudioCallback(AudioCallback callback, void* arg) { fAudioCallback = callback; fCallbackArg = arg; } void PerformAudioCallback(int frames) { if (fAudioCallback) { fAudioCallback(frames, fInChannel, fOutChannel, fCallbackArg); } } }; typedef TiPhoneCoreAudioRenderer * TiPhoneCoreAudioRendererPtr; #endif 1.9.12~dfsg/macosx/remove_jackdmp0000755000000000000000000000063413214314510015551 0ustar rootroot# Remove jackdmp resources sudo rm -r "/usr/local/lib/jackmp" sudo rm "/usr/local/bin/jackdmp" sudo rm -r "/usr/local/lib/jackd" sudo rm "/usr/local/lib/libjackmp.dylib" sudo rm -r "/Library/Frameworks/Jackmp.framework" sudo rm -r "/Library/Frameworks/Jackservermp.framework" sudo rm -r "/Library/Frameworks/Jacknet.framework" sudo rm -r "/Library/Audio/Plug-Ins/HAL/JackRouter.plugin" # Tries to restore jack 1.9.12~dfsg/macosx/coremidi/0000755000000000000000000000000013214314510014425 5ustar rootroot1.9.12~dfsg/macosx/coremidi/JackCoreMidiVirtualOutputPort.mm0000644000000000000000000000554413214314510022711 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackError.h" #include "JackCoreMidiUtil.h" #include "JackCoreMidiVirtualOutputPort.h" using Jack::JackCoreMidiVirtualOutputPort; JackCoreMidiVirtualOutputPort:: JackCoreMidiVirtualOutputPort(const char *alias_name, const char *client_name, const char *driver_name, int base_index, int index, MIDIClientRef client, double time_ratio, size_t max_bytes, size_t max_messages): JackCoreMidiOutputPort(time_ratio, max_bytes, max_messages) { std::stringstream stream; stream << "virtual" << (base_index + 1); CFStringRef name = CFStringCreateWithCString(0, stream.str().c_str(), CFStringGetSystemEncoding()); if (! name) { throw std::bad_alloc(); } MIDIEndpointRef source; OSStatus status = MIDISourceCreate(client, name, &source); /* SInt32 value; status = MIDIObjectGetIntegerProperty(source, kMIDIPropertyUniqueID, &value); if (status == noErr) { jack_info("kMIDIPropertyUniqueID %d", value); } */ CFRelease(name); if (status != noErr) { throw std::runtime_error(GetMacOSErrorString(status)); } Initialize(alias_name, client_name, driver_name, index, source, 0); // Keep in global list (that keeps growing during the whole session...) endpoint_list.insert(GetEndpoint()); } JackCoreMidiVirtualOutputPort::~JackCoreMidiVirtualOutputPort() { OSStatus status = MIDIEndpointDispose(GetEndpoint()); if (status != noErr) { WriteMacOSError("JackCoreMidiVirtualOutputPort [destructor]", "MIDIEndpointDispose", status); } } bool JackCoreMidiVirtualOutputPort::SendPacketList(MIDIPacketList *packet_list) { OSStatus status = MIDIReceived(endpoint, packet_list); bool result = status == noErr; if (! result) { WriteMacOSError("JackCoreMidiVirtualOutputPort::SendPacketList", "MIDIReceived", status); } return result; } 1.9.12~dfsg/macosx/coremidi/JackCoreMidiPort.h0000644000000000000000000000323713214314510017734 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiPort__ #define __JackCoreMidiPort__ #include #include #include "JackConstants.h" namespace Jack { class JackCoreMidiPort { private: char alias[REAL_JACK_PORT_NAME_SIZE+1]; char name[REAL_JACK_PORT_NAME_SIZE+1]; bool initialized; protected: void Initialize(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIEndpointRef endpoint, bool is_output); double time_ratio; MIDIEndpointRef endpoint; MIDIEndpointRef GetEndpoint(); static std::set endpoint_list; public: JackCoreMidiPort(double time_ratio); virtual ~JackCoreMidiPort(); const char * GetAlias(); const char * GetName(); static bool IsInternalPort(MIDIObjectRef port_aux); }; } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiPhysicalInputPort.mm0000644000000000000000000000361213214314510022630 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackCoreMidiPhysicalInputPort.h" #include "JackCoreMidiUtil.h" using Jack::JackCoreMidiPhysicalInputPort; JackCoreMidiPhysicalInputPort:: JackCoreMidiPhysicalInputPort(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIClientRef client, MIDIPortRef internal_input, double time_ratio, size_t max_bytes, size_t max_messages): JackCoreMidiInputPort(time_ratio, max_bytes, max_messages) { MIDIEndpointRef source = MIDIGetSource(index); if (! source) { // X: Is there a way to get a better error message? std::stringstream stream; stream << "The source at index '" << index << "' is not available"; throw std::runtime_error(stream.str().c_str()); } OSStatus status = MIDIPortConnectSource(internal_input, source, this); if (status != noErr) { throw std::runtime_error(GetMacOSErrorString(status)); } Initialize(alias_name, client_name, driver_name, index, source); } JackCoreMidiPhysicalInputPort::~JackCoreMidiPhysicalInputPort() { // Empty } 1.9.12~dfsg/macosx/coremidi/JackCoreMidiPhysicalInputPort.h0000644000000000000000000000266413214314510022454 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiPhysicalInputPort__ #define __JackCoreMidiPhysicalInputPort__ #include "JackCoreMidiInputPort.h" namespace Jack { class JackCoreMidiPhysicalInputPort: public JackCoreMidiInputPort { public: JackCoreMidiPhysicalInputPort(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIClientRef client, MIDIPortRef internal_input, double time_ratio, size_t max_bytes=4096, size_t max_messages=1024); ~JackCoreMidiPhysicalInputPort(); }; } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiInputPort.h0000644000000000000000000000361113214314510020750 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiInputPort__ #define __JackCoreMidiInputPort__ #include "JackCoreMidiPort.h" #include "JackMidiAsyncQueue.h" #include "JackMidiBufferWriteQueue.h" namespace Jack { class JackCoreMidiInputPort: public JackCoreMidiPort { private: jack_nframes_t GetFramesFromTimeStamp(MIDITimeStamp timestamp); jack_midi_event_t *jack_event; jack_midi_data_t *sysex_buffer; size_t sysex_bytes_sent; jack_midi_data_t running_status_buf[3]; JackMidiAsyncQueue *thread_queue; JackMidiBufferWriteQueue *write_queue; protected: void Initialize(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIEndpointRef endpoint); public: JackCoreMidiInputPort(double time_ratio, size_t max_bytes=4096, size_t max_messages=1024); virtual ~JackCoreMidiInputPort(); void ProcessCoreMidi(const MIDIPacketList *packet_list); void ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); bool Start(); bool Stop(); }; } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiPhysicalOutputPort.h0000644000000000000000000000316013214314510022645 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiPhysicalOutputPort__ #define __JackCoreMidiPhysicalOutputPort__ #include "JackCoreMidiOutputPort.h" namespace Jack { class JackCoreMidiPhysicalOutputPort: public JackCoreMidiOutputPort { private: MIDIPortRef internal_output; protected: bool SendPacketList(MIDIPacketList *packet_list); public: JackCoreMidiPhysicalOutputPort(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIClientRef client, MIDIPortRef internal_output, double time_ratio, size_t max_bytes=4096, size_t max_messages=1024); ~JackCoreMidiPhysicalOutputPort(); }; } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiVirtualOutputPort.h0000644000000000000000000000272713214314510022527 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiVirtualOutputPort__ #define __JackCoreMidiVirtualOutputPort__ #include "JackCoreMidiOutputPort.h" namespace Jack { class JackCoreMidiVirtualOutputPort: public JackCoreMidiOutputPort { protected: bool SendPacketList(MIDIPacketList *packet_list); public: JackCoreMidiVirtualOutputPort(const char *alias_name, const char *client_name, const char *driver_name, int base_index, int index, MIDIClientRef client, double time_ratio, size_t max_bytes=4096, size_t max_messages=1024); ~JackCoreMidiVirtualOutputPort(); }; } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiDriver.mm0000644000000000000000000006701413214314510020430 0ustar rootroot/* Copyright (C) 2009 Grame Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackCompilerDeps.h" #include "JackCoreMidiDriver.h" #include "JackCoreMidiUtil.h" #include "JackEngineControl.h" #include "driver_interface.h" #include #include #include using Jack::JackCoreMidiDriver; static char capture_driver_name[256]; static char playback_driver_name[256]; static int in_channels, out_channels; static bool capturing, playing, monitor; static jack_nframes_t capture_latency, playback_latency; /////////////////////////////////////////////////////////////////////////////// // Static callbacks /////////////////////////////////////////////////////////////////////////////// void JackCoreMidiDriver::HandleInputEvent(const MIDIPacketList *packet_list, void *driver, void *port) { ((JackCoreMidiPhysicalInputPort *) port)->ProcessCoreMidi(packet_list); } void JackCoreMidiDriver::HandleNotificationEvent(const MIDINotification *message, void *driver) { ((JackCoreMidiDriver *) driver)->HandleNotification(message); } /////////////////////////////////////////////////////////////////////////////// // Class /////////////////////////////////////////////////////////////////////////////// JackCoreMidiDriver::JackCoreMidiDriver(const char *name, const char *alias, JackLockedEngine *engine, JackSynchro *table): JackMidiDriver(name, alias, engine, table),fThread(this) { mach_timebase_info_data_t info; kern_return_t result = mach_timebase_info(&info); if (result != KERN_SUCCESS) { throw std::runtime_error(mach_error_string(result)); } client = 0; fCaptureChannels = 0; fPlaybackChannels = 0; num_physical_inputs = 0; num_physical_outputs = 0; num_virtual_inputs = 0; num_virtual_outputs = 0; physical_input_ports = 0; physical_output_ports = 0; time_ratio = (((double) info.numer) / info.denom) / 1000.0; virtual_input_ports = 0; virtual_output_ports = 0; internal_input = 0; internal_output = 0; } JackCoreMidiDriver::~JackCoreMidiDriver() {} bool JackCoreMidiDriver::Init() { return OpenAux(); } bool JackCoreMidiDriver::OpenAux() { int pi_count = 0; int po_count = 0; int vi_count = 0; int vo_count = 0; ItemCount potential_po_count; ItemCount potential_pi_count; CFStringRef name = CFStringCreateWithCString(0, "JackMidi", CFStringGetSystemEncoding()); if (! name) { jack_error("JackCoreMidiDriver::Open - failed to allocate memory for " "client name string"); return false; } OSStatus status = MIDIClientCreate(name, HandleNotificationEvent, this, &client); CFRelease(name); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Open", "MIDIClientCreate", status); return false; } char *client_name = fClientControl.fName; // Allocate and connect physical inputs potential_pi_count = MIDIGetNumberOfSources(); if (potential_pi_count) { status = MIDIInputPortCreate(client, CFSTR("Physical Input Port"), HandleInputEvent, this, &internal_input); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Open", "MIDIInputPortCreate", status); goto destroy; } try { physical_input_ports = new JackCoreMidiPhysicalInputPort*[potential_pi_count]; } catch (std::exception& e) { jack_error("JackCoreMidiDriver::Open - while creating physical " "input port array: %s", e.what()); goto destroy; } for (ItemCount i = 0; i < potential_pi_count; i++) { try { physical_input_ports[pi_count] = new JackCoreMidiPhysicalInputPort(fAliasName, client_name, capture_driver_name, i, client, internal_input, time_ratio); } catch (std::exception& e) { jack_error("JackCoreMidiDriver::Open - while creating " "physical input port: %s", e.what()); goto destroy; } pi_count++; } } // Allocate and connect physical outputs potential_po_count = MIDIGetNumberOfDestinations(); if (potential_po_count) { status = MIDIOutputPortCreate(client, CFSTR("Physical Output Port"), &internal_output); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Open", "MIDIOutputPortCreate", status); goto destroy; } try { physical_output_ports = new JackCoreMidiPhysicalOutputPort*[potential_po_count]; } catch (std::exception& e) { jack_error("JackCoreMidiDriver::Open - while creating physical " "output port array: %s", e.what()); goto destroy; } for (ItemCount i = 0; i < potential_po_count; i++) { try { physical_output_ports[po_count] = new JackCoreMidiPhysicalOutputPort(fAliasName, client_name, playback_driver_name, i, client, internal_output, time_ratio); } catch (std::exception& e) { jack_error("JackCoreMidiDriver::Open - while creating " "physical output port: %s", e.what()); goto destroy; } po_count++; } } // Allocate and connect virtual inputs if (in_channels) { try { virtual_input_ports = new JackCoreMidiVirtualInputPort*[in_channels]; } catch (std::exception& e) { jack_error("JackCoreMidiDriver::Open - while creating virtual " "input port array: %s", e.what()); goto destroy; } for (vi_count = 0; vi_count < in_channels; vi_count++) { try { virtual_input_ports[vi_count] = new JackCoreMidiVirtualInputPort(fAliasName, client_name, capture_driver_name, vi_count, vi_count + pi_count, client, time_ratio); } catch (std::exception& e) { jack_error("JackCoreMidiDriver::Open - while creating virtual " "input port: %s", e.what()); goto destroy; } } } // Allocate and connect virtual outputs if (out_channels) { try { virtual_output_ports = new JackCoreMidiVirtualOutputPort*[out_channels]; } catch (std::exception& e) { jack_error("JackCoreMidiDriver::Open - while creating virtual " "output port array: %s", e.what()); goto destroy; } for (vo_count = 0; vo_count < out_channels; vo_count++) { try { virtual_output_ports[vo_count] = new JackCoreMidiVirtualOutputPort(fAliasName, client_name, playback_driver_name, vo_count, vo_count + po_count, client, time_ratio); } catch (std::exception& e) { jack_error("JackCoreMidiDriver::Open - while creating virtual " "output port: %s", e.what()); goto destroy; } } } if (! (pi_count || po_count || in_channels || out_channels)) { jack_error("JackCoreMidiDriver::Open - no CoreMIDI inputs or outputs " "found, and no virtual ports allocated."); } if (! JackMidiDriver::Open(capturing, playing, in_channels + pi_count, out_channels + po_count, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency)) { num_physical_inputs = pi_count; num_physical_outputs = po_count; num_virtual_inputs = in_channels; num_virtual_outputs = out_channels; return true; } destroy: if (physical_input_ports) { for (int i = 0; i < pi_count; i++) { delete physical_input_ports[i]; } delete[] physical_input_ports; physical_input_ports = 0; } if (physical_output_ports) { for (int i = 0; i < po_count; i++) { delete physical_output_ports[i]; } delete[] physical_output_ports; physical_output_ports = 0; } if (virtual_input_ports) { for (int i = 0; i < vi_count; i++) { delete virtual_input_ports[i]; } delete[] virtual_input_ports; virtual_input_ports = 0; } if (virtual_output_ports) { for (int i = 0; i < vo_count; i++) { delete virtual_output_ports[i]; } delete[] virtual_output_ports; virtual_output_ports = 0; } if (internal_output) { status = MIDIPortDispose(internal_output); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Open", "MIDIPortDispose", status); } } if (internal_input) { status = MIDIPortDispose(internal_input); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Open", "MIDIPortDispose", status); } } if (client) { status = MIDIClientDispose(client); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Open", "MIDIClientDispose", status); } } // Default open if (! JackMidiDriver::Open(capturing, playing, in_channels + pi_count, out_channels + po_count, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency)) { client = 0; num_physical_inputs = 0; num_physical_outputs = 0; num_virtual_inputs = 0; num_virtual_outputs = 0; return true; } else { return false; } } bool JackCoreMidiDriver::Execute() { CFRunLoopRun(); return false; } int JackCoreMidiDriver::Attach() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; jack_port_id_t index; jack_nframes_t latency = buffer_size; jack_latency_range_t latency_range; const char *name; JackPort *port; JackCoreMidiPort *port_obj; latency_range.max = latency; latency_range.min = latency; // Physical inputs for (int i = 0; i < num_physical_inputs; i++) { port_obj = physical_input_ports[i]; name = port_obj->GetName(); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, buffer_size, &index) < 0) { jack_error("JackCoreMidiDriver::Attach - cannot register physical " "input port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(port_obj->GetAlias()); port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[i] = index; } // Virtual inputs for (int i = 0; i < num_virtual_inputs; i++) { port_obj = virtual_input_ports[i]; name = port_obj->GetName(); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, buffer_size, &index) < 0) { jack_error("JackCoreMidiDriver::Attach - cannot register virtual " "input port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(port_obj->GetAlias()); port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[num_physical_inputs + i] = index; } if (! fEngineControl->fSyncMode) { latency += buffer_size; latency_range.max = latency; latency_range.min = latency; } // Physical outputs for (int i = 0; i < num_physical_outputs; i++) { port_obj = physical_output_ports[i]; name = port_obj->GetName(); fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, buffer_size, &index); if (index == NO_PORT) { jack_error("JackCoreMidiDriver::Attach - cannot register physical " "output port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(port_obj->GetAlias()); port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[i] = index; } // Virtual outputs for (int i = 0; i < num_virtual_outputs; i++) { port_obj = virtual_output_ports[i]; name = port_obj->GetName(); fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, buffer_size, &index); if (index == NO_PORT) { jack_error("JackCoreMidiDriver::Attach - cannot register virtual " "output port with name '%s'.", name); // X: Do we need to deallocate ports? return -1; } port = fGraphManager->GetPort(index); port->SetAlias(port_obj->GetAlias()); port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[num_physical_outputs + i] = index; } return 0; } int JackCoreMidiDriver::Close() { fThread.Kill(); return CloseAux(); } int JackCoreMidiDriver::CloseAux() { // Generic MIDI driver close int result = JackMidiDriver::Close(); OSStatus status; if (physical_input_ports) { for (int i = 0; i < num_physical_inputs; i++) { delete physical_input_ports[i]; } delete[] physical_input_ports; num_physical_inputs = 0; physical_input_ports = 0; if (internal_input) { status = MIDIPortDispose(internal_input); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Close", "MIDIPortDispose", status); result = -1; } internal_input = 0; } } if (physical_output_ports) { for (int i = 0; i < num_physical_outputs; i++) { delete physical_output_ports[i]; } delete[] physical_output_ports; num_physical_outputs = 0; physical_output_ports = 0; if (internal_output) { status = MIDIPortDispose(internal_output); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Close", "MIDIPortDispose", status); result = -1; } internal_output = 0; } } if (virtual_input_ports) { for (int i = 0; i < num_virtual_inputs; i++) { delete virtual_input_ports[i]; } delete[] virtual_input_ports; num_virtual_inputs = 0; virtual_input_ports = 0; } if (virtual_output_ports) { for (int i = 0; i < num_virtual_outputs; i++) { delete virtual_output_ports[i]; } delete[] virtual_output_ports; num_virtual_outputs = 0; virtual_output_ports = 0; } if (client) { status = MIDIClientDispose(client); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Close", "MIDIClientDispose", status); result = -1; } client = 0; } return result; } void JackCoreMidiDriver::Restart() { // Lock between this thread and RT thread JackLock lock(this); // Lock between this thread and request thread if (fEngine->Lock()) { // Use first alias SaveConnections(1); Stop(); Detach(); CloseAux(); OpenAux(); Attach(); Start(); // Use first alias and partial port naming LoadConnections(1, false); fEngine->Unlock(); } else { jack_error("Cannot acquire engine lock..."); } } void JackCoreMidiDriver::HandleNotification(const MIDINotification *message) { switch (message->messageID) { case kMIDIMsgObjectAdded: { /* We don't want to restart when our internal virtual in/out are created. */ const MIDIObjectAddRemoveNotification* add_message = reinterpret_cast(message); if (!JackCoreMidiPort::IsInternalPort(add_message->child)) { Restart(); } break; } case kMIDIMsgObjectRemoved: { /* We don't want to restart when our internal virtual in/out are created. */ const MIDIObjectAddRemoveNotification* remove_message = reinterpret_cast(message); if (!JackCoreMidiPort::IsInternalPort(remove_message->child)) { Restart(); } break; } } } int JackCoreMidiDriver::Open(bool capturing_aux, bool playing_aux, int in_channels_aux, int out_channels_aux, bool monitor_aux, const char* capture_driver_name_aux, const char* playback_driver_name_aux, jack_nframes_t capture_latency_aux, jack_nframes_t playback_latency_aux) { strcpy(capture_driver_name, capture_driver_name_aux); strcpy(playback_driver_name, playback_driver_name_aux); capturing = capturing_aux; playing = playing_aux; in_channels = in_channels_aux; out_channels = out_channels_aux; monitor = monitor_aux; capture_latency = capture_latency_aux; playback_latency = playback_latency_aux; fThread.StartSync(); int count = 0; while (fThread.GetStatus() != JackThread::kRunning && ++count < WAIT_COUNTER) { JackSleep(100000); jack_log("JackCoreMidiDriver::Open wait count = %d", count); } if (count == WAIT_COUNTER) { jack_info("Cannot open CoreMIDI driver"); fThread.Kill(); return -1; } else { JackSleep(10000); jack_info("CoreMIDI driver is opened..."); } return 0; } int JackCoreMidiDriver::Start() { jack_info("JackCoreMidiDriver::Start - Starting driver."); JackMidiDriver::Start(); int pi_count = 0; int po_count = 0; int vi_count = 0; int vo_count = 0; jack_info("JackCoreMidiDriver::Start - Enabling physical input ports."); for (; pi_count < num_physical_inputs; pi_count++) { if (physical_input_ports[pi_count]->Start() < 0) { jack_error("JackCoreMidiDriver::Start - Failed to enable physical " "input port."); goto stop_physical_input_ports; } } jack_info("JackCoreMidiDriver::Start - Enabling physical output ports."); for (; po_count < num_physical_outputs; po_count++) { if (physical_output_ports[po_count]->Start() < 0) { jack_error("JackCoreMidiDriver::Start - Failed to enable physical " "output port."); goto stop_physical_output_ports; } } jack_info("JackCoreMidiDriver::Start - Enabling virtual input ports."); for (; vi_count < num_virtual_inputs; vi_count++) { if (virtual_input_ports[vi_count]->Start() < 0) { jack_error("JackCoreMidiDriver::Start - Failed to enable virtual " "input port."); goto stop_virtual_input_ports; } } jack_info("JackCoreMidiDriver::Start - Enabling virtual output ports."); for (; vo_count < num_virtual_outputs; vo_count++) { if (virtual_output_ports[vo_count]->Start() < 0) { jack_error("JackCoreMidiDriver::Start - Failed to enable virtual " "output port."); goto stop_virtual_output_ports; } } jack_info("JackCoreMidiDriver::Start - Driver started."); return 0; stop_virtual_output_ports: for (int i = 0; i < vo_count; i++) { if (virtual_output_ports[i]->Stop() < 0) { jack_error("JackCoreMidiDriver::Start - Failed to disable virtual " "output port."); } } stop_virtual_input_ports: for (int i = 0; i < vi_count; i++) { if (virtual_input_ports[i]->Stop() < 0) { jack_error("JackCoreMidiDriver::Start - Failed to disable virtual " "input port."); } } stop_physical_output_ports: for (int i = 0; i < po_count; i++) { if (physical_output_ports[i]->Stop() < 0) { jack_error("JackCoreMidiDriver::Start - Failed to disable " "physical output port."); } } stop_physical_input_ports: for (int i = 0; i < pi_count; i++) { if (physical_input_ports[i]->Stop() < 0) { jack_error("JackCoreMidiDriver::Start - Failed to disable " "physical input port."); } } return -1; } int JackCoreMidiDriver::Stop() { int result = 0; JackMidiDriver::Stop(); jack_info("JackCoreMidiDriver::Stop - disabling physical input ports."); for (int i = 0; i < num_physical_inputs; i++) { if (physical_input_ports[i]->Stop() < 0) { jack_error("JackCoreMidiDriver::Stop - Failed to disable physical " "input port."); result = -1; } } jack_info("JackCoreMidiDriver::Stop - disabling physical output ports."); for (int i = 0; i < num_physical_outputs; i++) { if (physical_output_ports[i]->Stop() < 0) { jack_error("JackCoreMidiDriver::Stop - Failed to disable physical " "output port."); result = -1; } } jack_info("JackCoreMidiDriver::Stop - disabling virtual input ports."); for (int i = 0; i < num_virtual_inputs; i++) { if (virtual_input_ports[i]->Stop() < 0) { jack_error("JackCoreMidiDriver::Stop - Failed to disable virtual " "input port."); result = -1; } } jack_info("JackCoreMidiDriver::Stop - disabling virtual output ports."); for (int i = 0; i < num_virtual_outputs; i++) { if (virtual_output_ports[i]->Stop() < 0) { jack_error("JackCoreMidiDriver::Stop - Failed to disable virtual " "output port."); result = -1; } } return result; } int JackCoreMidiDriver::ProcessRead() { int res; if (Trylock()) { res = (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); Unlock(); } else { res = -1; } return res; } int JackCoreMidiDriver::ProcessWrite() { int res; if (Trylock()) { res = (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync(); Unlock(); } else { res = -1; } return res; } int JackCoreMidiDriver::Read() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < num_physical_inputs; i++) { physical_input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); } for (int i = 0; i < num_virtual_inputs; i++) { virtual_input_ports[i]-> ProcessJack(GetInputBuffer(num_physical_inputs + i), buffer_size); } return 0; } int JackCoreMidiDriver::Write() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < num_physical_outputs; i++) { physical_output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); } for (int i = 0; i < num_virtual_outputs; i++) { virtual_output_ports[i]-> ProcessJack(GetOutputBuffer(num_physical_outputs + i), buffer_size); } return 0; } #ifdef __cplusplus extern "C" { #endif // singleton kind of driver static Jack::JackCoreMidiDriver* driver = NULL; SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() { jack_driver_desc_t * desc; jack_driver_desc_filler_t filler; jack_driver_param_value_t value; desc = jack_driver_descriptor_construct("coremidi", JackDriverSlave, "Apple CoreMIDI API based MIDI backend", &filler); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "CoreMIDI virtual bus", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "CoreMIDI virtual bus", NULL); return desc; } SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { const JSList * node; const jack_driver_param_t * param; int virtual_in = 2; int virtual_out = 2; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { case 'i': virtual_in = param->value.ui; break; case 'o': virtual_out = param->value.ui; break; } } // singleton kind of driver if (!driver) { driver = new Jack::JackCoreMidiDriver("system_midi", "coremidi", engine, table); if (driver->Open(1, 1, virtual_in, virtual_out, false, "in", "out", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } } else { jack_info("JackCoreMidiDriver already allocated, cannot be loaded twice"); return NULL; } } #ifdef __cplusplus } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiUtil.mm0000644000000000000000000000267213214314510020111 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackError.h" #include "JackCoreMidiUtil.h" std::string Jack::GetMacOSErrorString(OSStatus status) { NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil]; NSString *errorString = [error localizedDescription]; std::string returnString; if (errorString){ returnString = std::string([errorString UTF8String]); } else { returnString = std::string("No error"); } return returnString; } void Jack::WriteMacOSError(const char *jack_function, const char *mac_function, OSStatus status) { jack_error("%s - %s: %s", jack_function, mac_function, GetMacOSErrorString(status).c_str()); } 1.9.12~dfsg/macosx/coremidi/JackCoreMidiOutputPort.h0000644000000000000000000000433013214314510021150 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiOutputPort__ #define __JackCoreMidiOutputPort__ #include #include "JackCoreMidiPort.h" #include "JackMidiAsyncQueue.h" #include "JackMidiBufferReadQueue.h" #include "JackThread.h" namespace Jack { class JackCoreMidiOutputPort: public JackCoreMidiPort, public JackRunnableInterface { private: jack_midi_event_t * GetCoreMidiEvent(bool block); MIDITimeStamp GetTimeStampFromFrames(jack_nframes_t frames); static const size_t PACKET_BUFFER_SIZE = 65536; SInt32 advance_schedule_time; char packet_buffer[PACKET_BUFFER_SIZE]; JackMidiBufferReadQueue *read_queue; char semaphore_name[128]; JackThread *thread; JackMidiAsyncQueue *thread_queue; sem_t *thread_queue_semaphore; protected: virtual bool SendPacketList(MIDIPacketList *packet_list) = 0; void Initialize(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIEndpointRef endpoint, SInt32 advance_schedule_time); public: JackCoreMidiOutputPort(double time_ratio, size_t max_bytes=4096, size_t max_messages=1024); virtual ~JackCoreMidiOutputPort(); bool Execute(); bool Init(); void ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); bool Start(); bool Stop(); }; } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiPort.mm0000644000000000000000000000570013214314510020113 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "JackCoreMidiPort.h" #include "JackCoreMidiUtil.h" #include "JackError.h" using Jack::JackCoreMidiPort; std::set JackCoreMidiPort::endpoint_list; bool JackCoreMidiPort::IsInternalPort(MIDIObjectRef port_aux) { MIDIEndpointRef port = (MIDIEndpointRef)port_aux; return std::find(endpoint_list.begin(), endpoint_list.end(), port) != endpoint_list.end(); } JackCoreMidiPort::JackCoreMidiPort(double time_ratio) { initialized = false; this->time_ratio = time_ratio; } JackCoreMidiPort::~JackCoreMidiPort() { // Empty } const char * JackCoreMidiPort::GetAlias() { assert(initialized); return alias; } MIDIEndpointRef JackCoreMidiPort::GetEndpoint() { assert(initialized); return endpoint; } const char * JackCoreMidiPort::GetName() { assert(initialized); return name; } void JackCoreMidiPort::Initialize(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIEndpointRef endpoint, bool is_output) { char endpoint_name[REAL_JACK_PORT_NAME_SIZE+1]; CFStringRef endpoint_name_ref; int num = index + 1; Boolean res; OSStatus result = MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &endpoint_name_ref); if (result != noErr) { WriteMacOSError("JackCoreMidiPort::Initialize", "MIDIObjectGetStringProperty", result); goto get_basic_alias; } res = CFStringGetCString(endpoint_name_ref, endpoint_name, sizeof(endpoint_name), 0); CFRelease(endpoint_name_ref); if (!res) { jack_error("JackCoreMidiPort::Initialize - failed to allocate memory " "for endpoint name."); get_basic_alias: snprintf(alias, sizeof(alias), "%s:%s:%s%d", alias_name, driver_name, is_output ? "in" : "out", num); } else { snprintf(alias, sizeof(alias), "%s:%s:%s%d", alias_name, endpoint_name, is_output ? "in" : "out", num); } snprintf(name, sizeof(name), "%s:%s_%d", client_name, is_output ? "playback" : "capture", num); this->endpoint = endpoint; initialized = true; } 1.9.12~dfsg/macosx/coremidi/JackCoreMidiVirtualInputPort.mm0000644000000000000000000000634413214314510022507 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackError.h" #include "JackCoreMidiUtil.h" #include "JackCoreMidiVirtualInputPort.h" using Jack::JackCoreMidiVirtualInputPort; /////////////////////////////////////////////////////////////////////////////// // Static callbacks /////////////////////////////////////////////////////////////////////////////// void JackCoreMidiVirtualInputPort:: HandleInputEvent(const MIDIPacketList *packet_list, void *port, void */*src_ref*/) { ((JackCoreMidiVirtualInputPort *) port)->ProcessCoreMidi(packet_list); } /////////////////////////////////////////////////////////////////////////////// // Class /////////////////////////////////////////////////////////////////////////////// JackCoreMidiVirtualInputPort:: JackCoreMidiVirtualInputPort(const char *alias_name, const char *client_name, const char *driver_name, int base_index, int index, MIDIClientRef client, double time_ratio, size_t max_bytes, size_t max_messages): JackCoreMidiInputPort(time_ratio, max_bytes, max_messages) { std::stringstream stream; stream << "virtual" << (base_index + 1); CFStringRef name = CFStringCreateWithCString(0, stream.str().c_str(), CFStringGetSystemEncoding()); if (! name) { throw std::bad_alloc(); } MIDIEndpointRef destination; OSStatus status = MIDIDestinationCreate(client, name, HandleInputEvent, this, &destination); /* SInt32 value; status = MIDIObjectGetIntegerProperty(destination, kMIDIPropertyUniqueID, &value); if (status == noErr) { jack_info("kMIDIPropertyUniqueID %d", value); } */ CFRelease(name); if (status != noErr) { throw std::runtime_error(GetMacOSErrorString(status)); } Initialize(alias_name, client_name, driver_name, index, destination); // Keep in global list (that keeps growing during the whole session...) endpoint_list.insert(endpoint); } JackCoreMidiVirtualInputPort::~JackCoreMidiVirtualInputPort() { OSStatus status = MIDIEndpointDispose(GetEndpoint()); if (status != noErr) { WriteMacOSError("JackCoreMidiVirtualInputPort [destructor]", "MIDIEndpointDispose", status); } } 1.9.12~dfsg/macosx/coremidi/JackCoreMidiUtil.h0000644000000000000000000000176413214314510017730 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiUtil__ #define __JackCoreMidiUtil__ #include #include namespace Jack { std::string GetMacOSErrorString(OSStatus status); void WriteMacOSError(const char *jack_function, const char *mac_function, OSStatus status); } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiInputPort.mm0000644000000000000000000002267313214314510021143 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackCoreMidiInputPort.h" #include "JackMidiUtil.h" #include "JackError.h" using Jack::JackCoreMidiInputPort; /** * Takes a MIDI status byte as argument and returns the expected size of the * associated MIDI event. Returns -1 on invalid status bytes AND on variable * size events (SysEx events). */ inline static int _expectedEventSize(const unsigned char& byte) { if (byte < 0x80) return -1; // not a valid status byte if (byte < 0xC0) return 3; // note on/off, note pressure, control change if (byte < 0xE0) return 2; // program change, channel pressure if (byte < 0xF0) return 3; // pitch wheel if (byte == 0xF0) return -1; // sysex message (variable size) if (byte == 0xF1) return 2; // time code per quarter frame if (byte == 0xF2) return 3; // sys. common song position pointer if (byte == 0xF3) return 2; // sys. common song select if (byte == 0xF4) return -1; // sys. common undefined / reserved if (byte == 0xF5) return -1; // sys. common undefined / reserved return 1; // tune request, end of SysEx, system real-time events } JackCoreMidiInputPort::JackCoreMidiInputPort(double time_ratio, size_t max_bytes, size_t max_messages): JackCoreMidiPort(time_ratio) { thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); std::auto_ptr thread_queue_ptr(thread_queue); write_queue = new JackMidiBufferWriteQueue(); std::auto_ptr write_queue_ptr(write_queue); sysex_buffer = new jack_midi_data_t[max_bytes]; write_queue_ptr.release(); thread_queue_ptr.release(); jack_event = 0; running_status_buf[0] = 0; } JackCoreMidiInputPort::~JackCoreMidiInputPort() { delete thread_queue; delete write_queue; delete[] sysex_buffer; } jack_nframes_t JackCoreMidiInputPort::GetFramesFromTimeStamp(MIDITimeStamp timestamp) { return GetFramesFromTime((jack_time_t) (timestamp * time_ratio)); } void JackCoreMidiInputPort::Initialize(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIEndpointRef endpoint) { JackCoreMidiPort::Initialize(alias_name, client_name, driver_name, index, endpoint, false); } void JackCoreMidiInputPort::ProcessCoreMidi(const MIDIPacketList *packet_list) { set_threaded_log_function(); // TODO: maybe parsing should be done by JackMidiRawInputWriteQueue instead unsigned int packet_count = packet_list->numPackets; assert(packet_count); MIDIPacket *packet = (MIDIPacket *) packet_list->packet; for (unsigned int i = 0; i < packet_count; i++) { jack_midi_data_t *data = packet->data; size_t size = packet->length; assert(size); jack_midi_event_t event; // In a MIDIPacket there can be more than one (non SysEx) MIDI event. // However if the packet contains a SysEx event, it is guaranteed that // there are no other events in the same MIDIPacket. int k = 0; // index of the current MIDI event within current MIDIPacket int eventSize = 0; // theoretical size of the current MIDI event int chunkSize = 0; // actual size of the current MIDI event data consumed // XX: There might be dragons in my spaghetti. This code is begging // for a rewrite. if (sysex_bytes_sent) { if (data[0] & 0x80) { jack_error("JackCoreMidiInputPort::ProcessCoreMidi - System " "exclusive message aborted."); sysex_bytes_sent = 0; goto parse_event; } buffer_sysex_bytes: if ((sysex_bytes_sent + size) <= sizeof(sysex_buffer)) { memcpy(sysex_buffer + sysex_bytes_sent, packet, size * sizeof(jack_midi_data_t)); } sysex_bytes_sent += size; if (data[size - 1] == 0xf7) { if (sysex_bytes_sent > sizeof(sysex_buffer)) { jack_error("JackCoreMidiInputPort::ProcessCoreMidi - " "Could not buffer a %d-byte system exclusive " "message. Discarding message.", sysex_bytes_sent); sysex_bytes_sent = 0; goto get_next_packet; } event.buffer = sysex_buffer; event.size = sysex_bytes_sent; sysex_bytes_sent = 0; k = size; // don't loop in a MIDIPacket if its a SysEx goto send_event; } goto get_next_packet; } parse_event: if (data[k+0] == 0xf0) { // Must actually never happen, since CoreMIDI guarantees a SysEx // message to be alone in one MIDIPaket, but safety first. The SysEx // buffer code is not written to handle this case, so skip packet. if (k != 0) { jack_error("JackCoreMidiInputPort::ProcessCoreMidi - Non " "isolated SysEx message in one packet, discarding."); goto get_next_packet; } if (data[size - 1] != 0xf7) { goto buffer_sysex_bytes; } } // not a regular status byte ? if (!(data[k+0] & 0x80) && running_status_buf[0]) { // "running status" mode ... eventSize = _expectedEventSize(running_status_buf[0]); chunkSize = (eventSize < 0) ? size - k : eventSize - 1; if (chunkSize <= 0) goto get_next_packet; if (chunkSize + 1 <= sizeof(running_status_buf)) { memcpy(&running_status_buf[1], &data[k], chunkSize); event.buffer = running_status_buf; event.size = chunkSize + 1; k += chunkSize; goto send_event; } } // valid status byte (or invalid "running status") ... eventSize = _expectedEventSize(data[k+0]); if (eventSize < 0) eventSize = size - k; if (eventSize <= 0) goto get_next_packet; event.buffer = &data[k]; event.size = eventSize; // store status byte for eventual "running status" in next event if (data[k+0] & 0x80) { if (data[k+0] < 0xf0) { // "running status" is only allowed for channel messages running_status_buf[0] = data[k+0]; } else if (data[k+0] < 0xf8) { // "system common" messages (0xf0..0xf7) shall reset any running // status, however "realtime" messages (0xf8..0xff) shall be // ignored here running_status_buf[0] = 0; } } k += eventSize; send_event: event.time = GetFramesFromTimeStamp(packet->timeStamp); switch (thread_queue->EnqueueEvent(&event)) { case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackCoreMidiInputPort::ProcessCoreMidi - The thread " "queue buffer is full. Dropping event."); break; case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackCoreMidiInputPort::ProcessCoreMidi - The thread " "queue couldn't enqueue a %d-byte packet. Dropping " "event.", event.size); break; default: ; } if (k < size) goto parse_event; get_next_packet: packet = MIDIPacketNext(packet); assert(packet); } } void JackCoreMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { write_queue->ResetMidiBuffer(port_buffer, frames); if (! jack_event) { jack_event = thread_queue->DequeueEvent(); } for (; jack_event; jack_event = thread_queue->DequeueEvent()) { // Add 'frames' to MIDI events to align with audio. switch (write_queue->EnqueueEvent(jack_event, frames)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackCoreMidiInputPort::ProcessJack - The write queue " "couldn't enqueue a %d-byte event. Dropping event.", jack_event->size); // Fallthrough on purpose case JackMidiWriteQueue::OK: continue; default: ; } break; } } bool JackCoreMidiInputPort::Start() { // Hack: Get rid of any messages that might have come in before starting // the engine. while (thread_queue->DequeueEvent()); sysex_bytes_sent = 0; running_status_buf[0] = 0; return true; } bool JackCoreMidiInputPort::Stop() { return true; } 1.9.12~dfsg/macosx/coremidi/JackCoreMidiOutputPort.mm0000644000000000000000000002103413214314510021332 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include "JackCoreMidiOutputPort.h" #include "JackMidiUtil.h" #include "JackTime.h" #include "JackError.h" using Jack::JackCoreMidiOutputPort; JackCoreMidiOutputPort::JackCoreMidiOutputPort(double time_ratio, size_t max_bytes, size_t max_messages): JackCoreMidiPort(time_ratio) { read_queue = new JackMidiBufferReadQueue(); std::auto_ptr read_queue_ptr(read_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); std::auto_ptr thread_queue_ptr(thread_queue); thread = new JackThread(this); std::auto_ptr thread_ptr(thread); snprintf(semaphore_name, sizeof(semaphore_name), "coremidi_%p", this); thread_queue_semaphore = sem_open(semaphore_name, O_CREAT, 0777, 0); if (thread_queue_semaphore == (sem_t *) SEM_FAILED) { throw std::runtime_error(strerror(errno)); } advance_schedule_time = 0; thread_ptr.release(); thread_queue_ptr.release(); read_queue_ptr.release(); } JackCoreMidiOutputPort::~JackCoreMidiOutputPort() { delete thread; sem_close(thread_queue_semaphore); sem_unlink(semaphore_name); delete read_queue; delete thread_queue; } bool JackCoreMidiOutputPort::Execute() { jack_midi_event_t *event = 0; MIDIPacketList *packet_list = (MIDIPacketList *) packet_buffer; for (;;) { MIDIPacket *packet = MIDIPacketListInit(packet_list); assert(packet); if (! event) { event = GetCoreMidiEvent(true); } jack_midi_data_t *data = event->buffer; jack_nframes_t send_frame = event->time; jack_time_t send_time = GetTimeFromFrames(send_frame) - advance_schedule_time; size_t size = event->size; MIDITimeStamp timestamp = GetTimeStampFromFrames(send_frame); packet = MIDIPacketListAdd(packet_list, PACKET_BUFFER_SIZE, packet, timestamp, size, data); if (packet) { do { if (GetMicroSeconds() >= send_time) { event = 0; break; } event = GetCoreMidiEvent(false); if (! event) { break; } packet = MIDIPacketListAdd(packet_list, sizeof(packet_buffer), packet, GetTimeStampFromFrames(event->time), event->size, event->buffer); } while (packet); SendPacketList(packet_list); } else { // We have a large system exclusive event. We'll have to send it // out in multiple packets. size_t bytes_sent = 0; do { packet = MIDIPacketListInit(packet_list); assert(packet); size_t num_bytes = 0; for (; bytes_sent < size; bytes_sent += num_bytes) { size_t num_bytes = size - bytes_sent; // We use 256 because the MIDIPacket struct defines the // size of the 'data' member to be 256 bytes. I believe // this prevents packets from being dynamically allocated // by 'MIDIPacketListAdd', but I might be wrong. if (num_bytes > 256) { num_bytes = 256; } packet = MIDIPacketListAdd(packet_list, sizeof(packet_buffer), packet, timestamp, num_bytes, data + bytes_sent); if (! packet) { break; } } if (! SendPacketList(packet_list)) { // An error occurred. The error message has already been // output. We lick our wounds and move along. break; } } while (bytes_sent < size); event = 0; } } return false; } jack_midi_event_t * JackCoreMidiOutputPort::GetCoreMidiEvent(bool block) { if (! block) { if (sem_trywait(thread_queue_semaphore)) { if (errno != EAGAIN) { jack_error("JackCoreMidiOutputPort::Execute - sem_trywait: %s", strerror(errno)); } return 0; } } else { while (sem_wait(thread_queue_semaphore)) { if (errno != EINTR) { jack_error("JackCoreMidiOutputPort::Execute - sem_wait: %s", strerror(errno)); return 0; } } } return thread_queue->DequeueEvent(); } MIDITimeStamp JackCoreMidiOutputPort::GetTimeStampFromFrames(jack_nframes_t frames) { return GetTimeFromFrames(frames) / time_ratio; } bool JackCoreMidiOutputPort::Init() { set_threaded_log_function(); // OSX only, values read in RT CoreMIDI thread UInt64 period = 0; UInt64 computation = 250 * 1000; UInt64 constraint = 500 * 1000; thread->SetParams(period, computation, constraint); if (thread->AcquireSelfRealTime()) { jack_error("JackCoreMidiOutputPort::Init - could not acquire realtime " "scheduling. Continuing anyway."); } return true; } void JackCoreMidiOutputPort::Initialize(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIEndpointRef endpoint, SInt32 advance_schedule_time) { JackCoreMidiPort::Initialize(alias_name, client_name, driver_name, index, endpoint, true); assert(advance_schedule_time >= 0); this->advance_schedule_time = advance_schedule_time; } void JackCoreMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { read_queue->ResetMidiBuffer(port_buffer); for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; event = read_queue->DequeueEvent()) { switch (thread_queue->EnqueueEvent(event, frames)) { case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackCoreMidiOutputPort::ProcessJack - The thread " "queue buffer is full. Dropping event."); break; case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackCoreMidiOutputPort::ProcessJack - The thread " "queue couldn't enqueue a %d-byte event. Dropping " "event.", event->size); break; default: if (sem_post(thread_queue_semaphore)) { jack_error("JackCoreMidiOutputPort::ProcessJack - unexpected " "error while posting to thread queue semaphore: %s", strerror(errno)); } } } } bool JackCoreMidiOutputPort::Start() { bool result = thread->GetStatus() != JackThread::kIdle; if (! result) { result = ! thread->StartSync(); if (! result) { jack_error("JackCoreMidiOutputPort::Start - failed to start MIDI " "processing thread."); } } return result; } bool JackCoreMidiOutputPort::Stop() { bool result = thread->GetStatus() == JackThread::kIdle; if (! result) { result = ! thread->Kill(); if (! result) { jack_error("JackCoreMidiOutputPort::Stop - failed to stop MIDI " "processing thread."); } } return result; } 1.9.12~dfsg/macosx/coremidi/JackCoreMidiPhysicalOutputPort.mm0000644000000000000000000000541213214314510023031 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackCoreMidiPhysicalOutputPort.h" #include "JackCoreMidiUtil.h" using Jack::JackCoreMidiPhysicalOutputPort; JackCoreMidiPhysicalOutputPort:: JackCoreMidiPhysicalOutputPort(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIClientRef client, MIDIPortRef internal_output, double time_ratio, size_t max_bytes, size_t max_messages): JackCoreMidiOutputPort(time_ratio, max_bytes, max_messages) { MIDIEndpointRef destination = MIDIGetDestination(index); if (! destination) { // X: Can we get a better error message? std::stringstream stream; stream << "The destination at index '" << index << "' is not available"; throw std::runtime_error(stream.str().c_str()); } SInt32 advance_schedule_time; OSStatus status = MIDIObjectGetIntegerProperty(destination, kMIDIPropertyAdvanceScheduleTimeMuSec, &advance_schedule_time); if (status != noErr) { WriteMacOSError("JackCoreMidiPhysicalOutputPort [constructor]", "MIDIObjectGetIntegerProperty", status); advance_schedule_time = 0; } else if (advance_schedule_time < 0) { advance_schedule_time = 0; } Initialize(alias_name, client_name, driver_name, index, destination, advance_schedule_time); this->internal_output = internal_output; } JackCoreMidiPhysicalOutputPort::~JackCoreMidiPhysicalOutputPort() { // Empty } bool JackCoreMidiPhysicalOutputPort::SendPacketList(MIDIPacketList *packet_list) { OSStatus status = MIDISend(internal_output, endpoint, packet_list); bool result = status == noErr; if (! result) { WriteMacOSError("JackCoreMidiPhysicalOutputPort::SendPacketList", "MIDISend", status); } return result; } 1.9.12~dfsg/macosx/coremidi/JackCoreMidiVirtualInputPort.h0000644000000000000000000000301413214314510022314 0ustar rootroot/* Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiVirtualInputPort__ #define __JackCoreMidiVirtualInputPort__ #include "JackCoreMidiInputPort.h" namespace Jack { class JackCoreMidiVirtualInputPort: public JackCoreMidiInputPort { private: static void HandleInputEvent(const MIDIPacketList *packet_list, void *port, void *src_ref); public: JackCoreMidiVirtualInputPort(const char *alias_name, const char *client_name, const char *driver_name, int base_index, int index, MIDIClientRef client, double time_ratio, size_t max_bytes=4096, size_t max_messages=1024); ~JackCoreMidiVirtualInputPort(); }; } #endif 1.9.12~dfsg/macosx/coremidi/JackCoreMidiDriver.h0000644000000000000000000000561513214314510020245 0ustar rootroot/* Copyright (C) 2009 Grame Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCoreMidiDriver__ #define __JackCoreMidiDriver__ #include "JackCoreMidiPhysicalInputPort.h" #include "JackCoreMidiPhysicalOutputPort.h" #include "JackCoreMidiVirtualInputPort.h" #include "JackCoreMidiVirtualOutputPort.h" #include "JackMidiDriver.h" #include "JackThread.h" namespace Jack { class JackCoreMidiDriver: public JackMidiDriver, public JackRunnableInterface, public JackLockAble { private: static void HandleInputEvent(const MIDIPacketList *packet_list, void *driver, void *port); static void HandleNotificationEvent(const MIDINotification *message, void *driver); void HandleNotification(const MIDINotification *message); MIDIClientRef client; MIDIPortRef internal_input; MIDIPortRef internal_output; int num_physical_inputs; int num_physical_outputs; int num_virtual_inputs; int num_virtual_outputs; JackCoreMidiPhysicalInputPort **physical_input_ports; JackCoreMidiPhysicalOutputPort **physical_output_ports; double time_ratio; JackCoreMidiVirtualInputPort **virtual_input_ports; JackCoreMidiVirtualOutputPort **virtual_output_ports; bool OpenAux(); int CloseAux(); void Restart(); JackThread fThread; /*! Thread to execute the Process function */ public: JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); ~JackCoreMidiDriver(); int Attach(); int Close(); int Open(bool capturing, bool playing, int num_inputs, int num_outputs, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); int Read(); int Start(); int Stop(); int Write(); int ProcessRead(); int ProcessWrite(); // JackRunnableInterface interface bool Init(); bool Execute(); }; } #define WAIT_COUNTER 100 #endif 1.9.12~dfsg/ChangeLog0000644000000000000000000020511713214314510013120 0ustar rootroot--------------------------- Contributors --------------------------- Dmitry Baikov Gabriel M. Beddingfield Steven Chamberlain Thom Johansen Thibault LeMeur Tom Szilagyi Andrzej Szombierski Kjetil S.Matheussen Pieter Palmers Tim Blechmann Marc-Olivier Barre Nedko Arnaudov Fernando Lopez-Lezcano Romain Moret Florian Faber Michael Voigt Torben Hohn Paul Davis Peter L Jones Devin Anderson Josh Green Mario Lang Arnold Krille Jan Engelhardt Adrian Knoth David Garcia Garzon Valerio Pilo Chris Caudle John Emmas Robin Gareus Matt Flax Lars-Peter Clausen Alexandru Tofan Kim Jeong Yeon Filipe Coelho --------------------------- Jackdmp changes log --------------------------- 2017-12-13 Filipe Coelho * Version 1.9.12 2017-06-13 Filipe Coelho * Version 1.9.11-RC1 2015-07-19 Filipe Coelho * Implement new jack_port_rename API 2014-07-20 Stephane Letz * Version 1.9.11 started. 2012-12-10 Stephane Letz * Version 1.9.10 started. 2012-11-21 Stephane Letz * Correct JackPortAudioDriver::Open : special case for ASIO drivers. 2012-10-20 Stephane Letz * Correct JackEngine::NotifyGraphReorder : graph-order callback now notified after port latencies update. 2012-09-22 Robin Gareus * netjack/opus: don't re-init en/decoders. 2012-09-18 Nedko Arnaudov * Use string ids in the alsa device list. 2012-09-10 Nedko Arnaudov * controlapi: fix double free on master switch. 2012-09-10 Robin Gareus * netjack1/netone opus support. * netjack1/2 Opus: use only 2bytes for encoded-length. * wscript: add header defines and libs for example-clients/netsource. * fix duplicate prog.includes. 2012-09-05 Stephane Letz * More robust channel mapping handling in JackCoreAudioDriver. 2012-09-05 Robin Gareus * Add opus support to NetJack2. 2012-08-21 Nedko Arnaudov * jack_control: fix epr command. 2012-08-21 Stephane Letz * Update JackCoreAudioDriver and JackCoreAudioAdapter with more recent API. 2012-08-03 Stephane Letz * Change framework installation hierarchy for OSX Mountain Lion. 2012-08-02 Stephane Letz * Devin Anderson patch for Jack/CoreMIDI duplicated messages. 2012-07-24 Stephane Letz * Fix in ALSA adapter. 2012-05-26 Nedko Arnaudov * Fix alsa driver parameter order. * Control API: Enforce driver/internal parameter order. 2012-05-24 Nedko Arnaudov * Extend jack_control to have parameter reset commands. 2012-03-24 Adrian Knoth * Align buffers to 32 byte boundaries to allow AVX processing. 2012-03-21 Stephane Letz * New jack_get_cycle_times() implementation from Fons Adriennsen. 2012-03-17 Nedko Arnaudov * Update waf. 2012-03-17 Adrian Knoth * [firewire] Introduce UpdateLatencies() in FFADO backend. * [firewire] Allow FFADO backend to change the buffer size. 2012-03-16 Stephane Letz * Rework JackMessageBuffer. 2012-03-15 Stephane Letz * POST_PACKED_STRUCTURE used for jack_latency_range_t type. 2012-03-09 Stephane Letz * Remove JACK_32_64 flag, so POST_PACKED_STRUCTURE now always used. 2012-02-10 Stephane Letz * Improve libjacknet master mode. 2012-02-09 Stephane Letz * In control API, UNIX like sigset_t replaced by more abstract jackctl_sigmask_t * opaque struct. 2012-02-01 Stephane Letz * Check server API callback from notification thread. * Use a time-out in notification channel write function. * Fix lock management in JackEngine. 2012-01-29 Stephane Letz * A bit more robust JackMessageBuffer implementation (in progress). 2012-01-27 Stephane Letz * Rename JackProcessSync in JackPosixProcessSync. 2012-01-26 Stephane Letz * Add EndTime function (especially for Windows). 2012-01-25 Stephane Letz * Fix NetJack2 initialisation bug. 2012-01-24 Stephane Letz * Improve ShutDown in NetManager. * Correct ShutDown in JackInternalClient and JackLibClient. 2012-01-20 Stephane Letz * Experimental system port alias use in Windows JackRouter. 2012-01-19 Stephane Letz * Implement shutdown for in server clients. * Better time-out management in NetJack2. 2012-01-13 Stephane Letz * More robust server/client protocol. 2012-01-11 Stephane Letz * Factorize code the server/client request in JackRequestDecoder class. 2012-01-06 Stephane Letz * Cleanup drivers and internals loading code. * jackctl_driver_params_parse API moved in public control.h. * More general drivers/internals loading model on Windows. 2012-01-06 Stephane Letz * Fix for compilation on Solaris. 2012-01-04 Stephane Letz * Fix library symbols export issue. 2012-01-02 Stephane Letz * Adrian Knoth fix in midiseq.c. 2011-12-20 Stephane Letz * Version 1.9.9 started. 2011-11-25 Stephane Letz * More robust dynamic port management in JACK/CoreMidi bridge. * Correct jack_port_name_size API. 2011-11-24 Stephane Letz * Dynamic port management in JACK/CoreMidi bridge. * Correct jack_client_create_thread (when realtime in on). 2011-11-21 Stephane Letz * John Emmas third auto-launch server on Windows patch. 2011-11-07 Stephane Letz * John Emmas first auto-launch server on Windows patch. * John Emmas second auto-launch server on Windows patch. 2011-11-06 Stephane Letz * Enable local access in NetJack2 code. 2011-11-04 Stephane Letz * Fix jack_set_port_name API. 2011-11-03 Stephane Letz * Add missing jack_client_get_uuid API. * John Emmas Windows server launching patch (1). 2011-10-28 Stephane Letz * John Emmas POST_PACKED_STRUCTURE patch. 2011-10-27 Stephane Letz * Gabriel Beddingfield patch (r4541) reverted. 2011-10-10 Stephane Letz * John Emmas patch for DSP CPU computation. 2011-09-27 Stephane Letz * Gabriel Beddingfield patch for ALSA driver: error when source is non-native byte-order float. 2011-08-31 Stephane Letz * Correct Start/Stop for Control API. 2011-08-30 Stephane Letz * Check driver type in jackdmp.cpp. 2011-08-28 Stephane Letz * Correct JackBasePosixMutex::Trylock. * Correct JackMessageBuffer::Execute. 2011-08-26 Stephane Letz * More robust code in synchronization primitives and in JackMessageBuffer. * Non blocking notifications in JackEngine::NotifyAddClient and JackEngine::NotifyRemoveClient. * More robust Control API implementation. * Add jackctl_driver_get_type in Control API. * Singleton behaviour for JackCoreMidiDriver and JackWinMMEDriver. 2011-07-29 Stephane Letz * New JackTimedDriver class to be used by JackDummyDriver, JackNetDriver and JackNetOneDriver classes. 2011-07-28 Stephane Letz * Enable explicit channel mapping in CoreAudio driver. 2011-07-25 Stephane Letz * NetJack2: no more timeout, correct JackWaitThreadedDriver::Execute. 2011-07-25 Stephane Letz * NetJack2: improve latency management, cleanup. 2011-07-23 Stephane Letz * Possible fix for http://trac.jackaudio.org/ticket/193. 2011-07-22 Stephane Letz * NetJack2: improve error reporting. 2011-07-16 Stephane Letz * Error in JackActivationCount::Signal now uses jack_log instead of jack_error. * EXPORT macro renamed to LIB_EXPORT. 2011-07-12 Stephane Letz * NetJack2 now only send data on network only is ports are connected both sides. 2011-07-11 Stephane Letz * Add JACK_NETJACK_PORT and JACK_NETJACK_MULTICAST environment variables for NetJack2. 2011-07-08 Stephane Letz * NetJack2 now only send data on network for connected ports. 2011-07-03 Stephane Letz * More debug code in JackMMCSS class. 2011-07-03 Stephane Letz * -l in JackCoreAudioDriver now display devices names and then quit. 2011-07-01 Stephane Letz * Fix bugs in JackNetAdapter. 2011-06-29 Stephane Letz * Special CATCH_CLOSE_EXCEPTION_RETURN to handle Close API calls. 2011-06-28 Stephane Letz * Another round of code improvements to handle completely buggy Digidesign CoreAudio user-land driver. 2011-06-20 Stephane Letz * Correct Dummy driver. 2011-06-17 Stephane Letz * NetJack2: connection error handling. 2011-06-16 Stephane Letz * Changes in NetJack2 connection management: no more timeout, any transmission error considered as fatal. * NetJack2: timeout again... 2011-06-11 Stephane Letz * Special version of jack_attach_shm/jack_release_shm on client side for POSIX shared memory, to solve a memory leak issue. 2011-06-10 Stephane Letz * SaveConnections/RestoreConnections in NetDriver. * SaveConnections/RestoreConnections moved in JackAudioDriver. 2011-06-09 Stephane Letz * Correct NetJack2 connection handling. 2011-05-27 Stephane Letz * Correct rd_acquire in dbus code. 2011-05-16 Stephane Letz * Correct OSX real-time thread setup. 2011-05-11 Stephane Letz * Correct MIDI in NetJack2. 2011-05-05 Stephane Letz * Libjacknet in progress. 2011-05-02 Stephane Letz * Merge branch switch-master-port-registration-notifications: correct driver port registration. 2011-04-21 Stephane Letz * CELT code for NetJack2. 2011-04-20 Stephane Letz * Add XRun detection in PortAudio driver. 2011-04-18 Stephane Letz * JackWeakAPI.cpp renamed in JackWeakAPI.c. 2011-04-04 Stephane Letz * Correct driver lifetime management. 2011-04-03 Stephane Letz * Fix in JackCoreAudioDriver::Read when there is no inputs. 2011-04-02 Stephane Letz * NetDriver can now ask for in/out values from the master (in progress). * Correct drivers parameter settings. 2011-04-01 Stephane Letz * Merge newer-midi branch (Devin Anderson redesign of the MIDI drivers: alsarawmidi, ffado, coremidi and winmme). * Cleanup JackThreadedDriver::Stop. * Correct JackNetOneDriver::Close. * Correction in jackdmp.cpp: notify_server_stop should be done after server destruction. * Improve error management in JackNetDriver. 2011-03-30 Stephane Letz * Version 1.9.8 started. 2011-03-29 Stephane Letz * Synchronize JackWeakAPI.cpp with new APIs. 2011-03-28 Stephane Letz * Correction of jack_connect/jack_disconnect: use of jack_activate and volatile keyword for thread shared variable. * Correction of JackNetOneDriver for latest CELT API. 2011-03-24 Stephane Letz * Implement renaming in JackDriver::Open to avoid name collision (thanks Devin Anderson). * Correct alsa_driver_restart (thanks Devin Anderson). 2011-03-23 Stephane Letz * Devin Anderson server-ctl-proposal branch merged on trunk: improved control API, slave backend reworked. 2011-03-14 Stephane Letz * Correct JackEngine::NotifyGraphReorder, update JackDebugClient with latest API. 2011-03-13 Stephane Letz * Rework internal slave driver management, JackServerGlobals now handle same parameters as jackdmp. 2011-03-11 Stephane Letz * Correct JackNetMaster::SetBufferSize. * Use jack_default_audio_sample_t instead of float consistently, fix ticket #201." * -X now allows to add several slave backends, add -I to load several internal clients. 2011-03-10 Stephane Letz * Latency callback must always be activated. * Correct TopologicalSort. * Add jack_midi_dump client. * Synchronize netjack1 with JACK1 version. * Synchronize jack_connect/jack_disconnect with JACK1 version. 2011-03-09 Stephane Letz * jack_client_has_session_callback implementation. * Fix jdelay for new latency API. * Check requested buffer size and limit to 1..8192 - avoids weird behaviour caused by jack_bufsize foobar. * jack_port_type_get_buffer_size implementation. * Stop using alloca and allocate buffer on the heap for alsa_io. * Rename jdelay to jack_iodelay as per Fons' request. * Call buffer size callback in activate (actually this is done on client side in the RT thread Init method). * JackEngine::ComputeTotalLatencies in progress. 2011-03-08 Stephane Letz * Use of latency range in all backends. * ComputeTotalLatencies now a client/server call. * Add latent test client for latency API. * Also print playback and capture latency in jack_lsp. 2011-03-04 Stephane Letz * Revert r4119 (RT notification in the server). JackAudioDriver::ProcessSync now skip backend write in case of graph process failure. * Fix incorrect error codes in alsa/usx2y.c and alsa/JackAlsaDriver.cpp. * Synchronize public headers with JACK1. Update OSX project. * New latency API implementation (in progress). 2011-02-09 Stephane Letz * Remove JackPortIsActive flag. 2011-02-07 Stephane Letz * Valerio Pilo second CAS for ARMv7 patch. 2011-02-03 Stephane Letz * Valerio Pilo CAS for ARMv7 patch. 2011-01-11 Stephane Letz * Adrian Knoth jack_lsp patch. 2010-11-17 Stephane Letz * ALSA backend: suspend/resume handling (jack1 r4075). * Correct dummy driver. 2010-11-05 Stephane Letz * In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start. * Correct symbols export in backends on OSX. 2010-11-03 Stephane Letz * Improve backend error handling: fatal error returned by Read/Write now cause a Process failure (so a thread exit for blocking backends). Recoverable ones (XRuns..) are now treated internally in ALSA, FreeBob and FFADO backends. 2010-10-30 Stephane Letz * Correct JackServer::Open to avoid a race when control API is used on OSX. 2010-10-29 Stephane Letz * Correct lsp.c code. * Add note about unique port-name requirement. 2010-09-08 Stephane Letz * Sync JackAlsaDriver::alsa_driver_check_card_type with JACK1 backend. 2010-08-30 Stephane Letz * Version 1.9.7 started. 2010-08-25 Stephane Letz * In JackCoreAudioDriver, fix an issue when no value is given for input. 2010-08-23 Stephane Letz * Adrian Knoth fix for linux cycle.h (ticket 188). 2010-07-07 Stephane Letz * Jan Engelhardt patch for get_cycles on SPARC. * Adrian Knoth hurd.patch, kfreebsd-fix.patch and alpha_ia64-sigsegv.patch from ticket 177. 2010-06-29 Stephane Letz * Arnold Krille firewire snooping patch. 2010-06-16 Stephane Letz * David Garcia Garzon unused_pkt_buf_field_jack2 netone patch. 2010-06-13 Stephane Letz * Fix JackPosixSemaphore::TimedWait: same behavior as JackPosixSemaphore::Wait regarding EINTR. 2010-05-31 Stephane Letz * Fix from Fernando Lopez-Lezcano for compilation on fc13. 2010-05-30 Stephane Letz * David Garcia Garzon netone patch. 2010-05-27 Stephane Letz * In JackCoreAudioDriver, move code called in MeasureCallback to be called once in IO thread. 2010-05-07 Stephane Letz * Add tests to validate intclient.h API. * On Linux, inter-process synchronization primitive switched to POSIX semaphore. 2010-04-16 Stephane Letz * Make jack_connect/jack_disconnect wait for effective port connection/disconnection. 2010-04-07 Stephane Letz * Remove call to exit in library code. 2010-03-26 Stephane Letz * ffado-portname-sync.patch from ticket #163 applied. 2010-03-24 Stephane Letz * On Windows, now use TRE library for regexp (BSD license instead of GPL license). 2010-03-19 Stephane Letz * Fix some file header to have library side code use LGPL. * Apply srcfactor.diff patch for ticket #162. 2010-03-06 Stephane Letz * Arnold Krille firewire patch. * Raise JACK_DRIVER_PARAM_STRING_MAX and JACK_PARAM_STRING_MAX to 127 otherwise some audio drivers cannot be loaded on OSX. 2010-03-04 Stephane Letz * Correct JackMachServerChannel::Execute: keep running even in error cases. * Raise JACK_PROTOCOL_VERSION number. 2010-03-03 Stephane Letz * Correct JackGraphManager::DeactivatePort. 2010-03-02 Stephane Letz * Improve JackCoreAudioDriver and JackCoreAudioAdapter: when no devices are described, takes default input and output and aggregate them. 2010-02-15 Stephane Letz * Version 1.9.6 started. 2010-01-29 Gabriel M. Beddingfield * Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. 2009-12-15 Stephane Letz * Shared memory manager was calling abort in case of fatal error, now return an error in caller. 2009-12-13 Stephane Letz * Mario Lang alsa_io time calculation overflow patch. 2009-12-10 Stephane Letz * Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. 2009-12-09 Stephane Letz * When threads are cancelled, the exception has to be rethrown. 2009-12-08 Stephane Letz * Josh Green ALSA driver capture only patch. 2009-12-03 Stephane Letz * Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). 2009-12-02 Stephane Letz * Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. * Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). * Check dynamic port-max value. 2009-12-01 Stephane Letz * Fix port_rename callback: now both old name and new name are given as parameters. 2009-11-30 Stephane Letz * Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). 2009-11-29 Stephane Letz * More robust sample rate change handling code in JackCoreAudioDriver. 2009-11-24 Stephane Letz * Dynamic choice of maximum port number. 2009-11-23 Stephane Letz * Peter L Jones patch for NetJack1 compilation on Windows. 2009-11-20 Stephane Letz * Version 1.9.5 started. * Client debugging code improved. 2009-11-18 Stephane Letz * Sync JackCoreAudioAdapter code with JackCoreAudioDriver. 2009-11-17 Stephane Letz * In JackCoreAudio driver, clock drift compensation in aggregated devices working. * In JackCoreAudio driver, clock drift compensation semantic changed a bit: when on, does not activate if not needed (same clock domain). 2009-11-16 Stephane Letz * In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. 2009-11-14 Stephane Letz * Sync with JACK1: -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. 2009-11-13 Stephane Letz * Better memory allocation error checking in ringbuffer.c, weak import improvements. * Memory allocation error checking for jack_client_new and jack_client_open (server and client side). * Memory allocation error checking in server for RPC. * Simplify server temporary mode: now use a JackTemporaryException. * Lock/Unlock shared memory segments (to test...). 2009-11-12 Stephane Letz * Better memory allocation error checking on client (library) side. 2009-11-11 Stephane Letz * Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. 2009-11-10 Stephane Letz * Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. 2009-11-09 Stephane Letz * Correct JackGraphManager::GetBuffer for the "client loop with one connection" case: buffer must be copied. 2009-11-07 Stephane Letz * Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). * Correct JackPosixThread::StartImp: thread priority setting now done in the RT case only. 2009-11-06 Stephane Letz * Correctly save and restore RT mode state in freewheel mode. * Correct freewheel code on client side. 2009-11-05 Stephane Letz * No reason to make jack_on_shutdown deprecated, so revert the incorrect change. * Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. 2009-10-30 Stephane Letz * In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. * In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. * Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fix...) * Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. * JACK_SCHED_POLICY switched to SCHED_FIFO. * Now can aggregate device that are themselves AD. 2009-10-29 Stephane Letz * In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). 2009-10-28 Stephane Letz * In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). * In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. 2009-10-27 Stephane Letz * Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. 2009-10-26 Stephane Letz * Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. * Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. 2009-10-25 Stephane Letz * Improve aggregate device management in JackCoreAudioDriver: now a "private" device only and cleanup properly. * Aggregate device code added to JackCoreAudioAdapter. 2009-10-23 Stephane Letz * Correct JackProcessSync::LockedTimedWait. * Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. * Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. * jack_verbose moved to JackGlobals class. 2009-10-22 Stephane Letz * Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. 2009-10-20 Stephane Letz * Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. * CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changed) 2009-10-17 Stephane Letz * Correct server temporary mode: now set a global and quit after server/client message handling is finished. 2009-10-15 Stephane Letz * Change CoreAudio notification thread setup for OSX Snow Leopard. 2009-09-18 Stephane Letz * Simplify transport in NetJack2: master only can control transport. 2009-09-15 Stephane Letz * Correct CPU timing in JackNetDriver, now take cycle begin time after Read. * Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. 2009-08-28 Stephane Letz * Correct monitor port naming in JackAudioDriver and JackCoreAudioDriver. * Big endian bug fix in memops.c (http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=11_be24bit.patch;att=1;bug=486308) 2009-07-31 Stephane Letz * Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. 2009-07-29 Stephane Letz * Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). 2009-07-28 Stephane Letz * Fix CopyAndConvertIn for Solaris backends. 2009-07-22 Stephane Letz * Version 1.9.4 started. * Solaris boomer backend now working in capture or playback only mode. * Fix control.h for proper compilation on Solaris. 2009-07-17 Stephane Letz * Loopback backend reborn as a dynamically loadable separated backend. * -L parameter for loopback backend activated again in jackd. 2009-07-17 Stephane Letz * Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. 2009-07-16 Stephane Letz * In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. 2009-07-15 Stephane Letz * Rename JackDriver::Init method to JackDriver::Initialize (to avoid confusion with JackThread::Init method). * Update Solaris boomer driver. * Report some cleanup and documentation improvements done on JACK1 timing functions. 2009-07-11 Stephane Letz * Raise drivers time out used in synchronous mode. 2009-07-09 Stephane Letz * Use __attribute__((__packed__)) again, more fixes for 64/32 mixed mode. * Torben Hohn changes for 64/32 mixed mode in wscripts. * Add compile time option for maximum ports per application. 2009-07-07 Stephane Letz * Use __attribute__((__aligned__(32))) instead of __attribute__((__packed__)) for 64/32 mixed mode. 2009-07-03 Stephane Letz * Another Tim Bechmann memops.c optimization patch. 2009-07-01 Stephane Letz * Tim Bechmann memops.c optimization patch. 2009-06-30 Stephane Letz * Tim Bechmann patch: hammerfall, only release monitor thread, if it has been created. 2009-06-19 Stephane Letz * Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. * NetJack2 code: better error checkout, method renaming. 2009-06-17 Stephane Letz * Move DBus based audio device reservation code in ALSA backend compilation. 2009-06-16 Stephane Letz * Correct JackFifo::TimedWait for EINTR handling. 2009-06-05 Stephane Letz * Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. 2009-05-18 Stephane Letz * Correct wcsript files to create jackdbus only (and not create jackd anymore) when compiled in --dbus mode, add a --classic option. Both options are possible but issue a warning. 2009-05-15 Stephane Letz * Move InitFrameTime in JackDriver::Start method. 2009-05-13 Stephane Letz * Reworked Torben Hohn fix for server restart issue on Windows. 2009-05-11 Stephane Letz * New jack_free function added in jack.h. * Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. 2009-05-07 Stephane Letz * Cleanup "loopback" stuff in server. 2009-05-06 Stephane Letz * Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). * D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. 2009-05-05 Stephane Letz * First working version of native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). 2009-04-22 Stephane Letz * jackctl_server_load_master renamed to jackctl_server_switch_master, jackctl_server_unload_master is removed. 2009-04-21 Stephane Letz * Add jackctl_server_load_master/jackctl_server_unload_master API. 2009-04-20 Stephane Letz * In ALSA audio card reservation code, tries to open the card even if reservation fails. * Clock source setting on Linux. 2009-04-08 Stephane Letz * Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver) in progress. 2009-04-03 Stephane Letz * Simplify JackClient RT code, jack_thread_wait API marked deprecated." 2009-03-29 Stephane Letz * Cleanup JackInternalClient code. 2009-03-27 Stephane Letz * Add a buffer size callback for netmaster that just remove the client (it will be recreated with the new parameters). 2009-03-26 Stephane Letz * First working JackBoomerDriver two threads version. 2009-03-24 Stephane Letz * New JackBoomerDriver class for Boomer driver on Solaris. * Add mixed 32/64 bits mode (off by default). 2009-03-23 Stephane Letz * Version 1.9.3 started. 2009-03-19 Stephane Letz * Tim Blechmann optimization patch (inlining some heavy used methods). 2009-03-12 Stephane Letz * Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). 2009-03-12 Stephane Letz * Try automatic adaptative mode in adapters. 2009-03-11 Stephane Letz * Client incorrect re-naming fixed: now done at socket level also. 2009-03-10 Stephane Letz * Add -g (ring-buffer) parameter to netadapter. * Automatic adaptative ringbuffer size mode when -g = 0. 2009-03-09 Stephane Letz * Use Torben Hohn PI controler code for adapters (in progress). 2009-03-05 Stephane Letz * Support for BIG_ENDIAN machines in NetJack2 for transport data. * Add auto_connect parameter in netmanager and netadapter. 2009-03-03 Stephane Letz * More robust profiling tools when clients come and go. 2009-03-01 Stephane Letz * Raise default port number to 1024. 2009-02-27 Stephane Letz * Improve generated gnuplot files for adapting code. 2009-02-25 Stephane Letz * Major cleanup in adapter code. 2009-02-25 Stephane Letz * Fix JackNetDriver::Close method. * For audio device reservation, add card_to_num function. * Fix buffer size and sample rate handling in JackAlsaAdapter. * Add control for adapter ringbuffer size. * Fix JackAlsaAdapter.h for 64 bits compilation. 2009-02-23 Stephane Letz * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. * Move generic code and data in JackNetInterface and JackNetMasterInterface classes. * First version of D-Bus based audio device reservation. 2009-02-20 Stephane Letz * Add InitConnection and InitRendering methods in JackNetSlaveInterface, better packet type checking in JackNetSlaveInterface::SyncRecv. * Change fMulticastIP handling in JackNetInterface. * Cleanup systemdeps.h on Windows. 2009-02-17 Stephane Letz * Fix the mutex/signal classes on Windows. * Client incorrect re-naming fixed: now done at fifo level only. 2009-02-16 Stephane Letz * Rework the mutex/signal classes. Use them in JackMessageBuffer. 2009-02-11 Stephane Letz * Merge Solaris branch back on trunk. * Equality of input and output buffer size removed (for now) in JackOSSDriver. 2009-02-10 Stephane Letz * Add a resample quality parameter in netadapter. 2009-02-09 Stephane Letz * Use PRIu32 kind of macro in JackAlsaDriver again. * Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). 2009-02-05 Stephane Letz * Add a resample quality parameter in audioadapter. 2009-02-01 Stephane Letz * Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. 2009-01-30 Stephane Letz * In NetJack2, fix a bug when capture or playback only channels are used. 2009-01-29 Stephane Letz * Support for "-h" option in internal clients to print the parameters. * Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. 2009-01-28 Stephane Letz * Support for BIG_ENDIAN machines in NetJack2. 2009-01-27 Stephane Letz * Better recovery of network overload situations, now "resynchronize" by skipping cycles." 2009-01-26 Stephane Letz * Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. * Fix in JackAlsaAdapter::Open. * Simplify audio packet order verification. * Set default mode to 'slow' in JackNetDriver and JackNetAdapter. 2009-01-19 Stephane Letz * Synchronize ALSA backend code with JACK1 one. 2009-01-17 Stephane Letz * JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. 2009-01-14 Stephane Letz * Cleanup server starting code for clients directly linked with libjackserver.so. 2009-01-09 Stephane Letz * JackProfiler scan already running clients (so can now be added anytime in the graph). 2009-01-09 Stephane Letz * New JackProfiler class for real-time server monitoring. 2009-01-07 Stephane Letz * Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. 2009-01-05 Stephane Letz * Synchronize jack2 public headers with JACK1 ones. * Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. 2008-12-18 Stephane Letz * For ALSA driver, synchronize with latest JACK1 memops functions. * Use memops functions in JackOSSDriver. * Use memops functions in JackOSSAdapter. 2008-12-17 Stephane Letz * Use JACK_DRIVER_DIR variable in internal clients loader. 2008-12-16 Stephane Letz * Fix JackOSSDriver::SetBufferSize (was crashing when restoring old size), fix ticket #111. * Force memory page in of profiling array in JackOSSDriver::Open. * Cleanup profiling code. * Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). 2008-12-08 Stephane Letz * Forbid JackOSSDriver to run in "aynchronous" mode, correct DSP CPU computation. 2008-12-04 Stephane Letz * More profiling in JackOSSDriver: sample conversion duration is measured. 2008-12-02 Stephane Letz * Optimize JackOSSDriver: no samples conversion if ports are not connected. 2008-12-01 Stephane Letz * Force preload of memory table in JackEngineProfiling. 2008-11-27 Stephane Letz * Add timing profiling code in JackOSSDriver. * Report ringbuffer.c fixes from JACK1. 2008-11-21 Stephane Letz * Report ringbuffer.c fixes from JACK1. * Better isolation of server and clients system resources to allow starting the server in several user account at the same time. * Correct ressource cleanup in case of driver open failure. 2008-11-19 Stephane Letz * Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. * Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. 2008-11-14 Stephane Letz * Version 1.9.1 started, fix symbols export in ringbuffer.c, cleanup on Windows. 2008-11-13 Stephane Letz * Fix jackctl_server_unload_internal. 2008-10-30 Stephane Letz * Correct JackClient::ShutDown. * TimeOut management in JackNetUnixSocket on Solaris. 2008-10-23 Stephane Letz * In JackOSSDriver, vmix mode is used by default, exclusif (O_EXCL) mode can be selected with -e option. * Fix a crash in JackEngine::Close when backend cannot be loaded. * Tim Blechmann optimization patch. * Backport of latest Paul alsa_seqmidi changes. 2008-10-15 Stephane Letz * Fix a conflict with Audio Hijack in JackCoreAudioDriver. 2008-10-09 Stephane Letz * Use a mutex to make jack_client_open/jack_client_close thread safe, remove use of jack_init/jack_uninit. 2008-10-08 Stephane Letz * Fix a SMP related bug introduced in rev 2957: remove the __SMP__ flag and define LOCK for SMP in all cases. 2008-10-02 Stephane Letz * Correct file permission for jack-shm-registry POSIX shared memory segment. * Checking for libsamplerate in waf, fix ticket #89." * Header cleanup, add --clients and --ports options in configure. 2008-09-22 Stephane Letz * Socket time out implementation on Solaris. * Fix a conflict with Audio Hijack in JackCoreAudioDriver. 2008-10-10 Stephane Letz * Improve OSS backend: SNDCTL_DSP_SETFRAGMENT must be done before, use of AFMT_S16_LE kind of values. 2008-10-09 Stephane Letz * First version of OSS backend. * Use a mutex to make jack_client_open/jack_client_close thread safe, remove use of jack_init/jack_uninit. 2008-10-08 Stephane Letz * Fix a SMP related bug introduced in rev 2957: remove the __SMP__ flag and define LOCK for SMP in all cases. 2008-10-03 Stephane Letz * Add engine profiling tools. 2008-10-02 Stephane Letz * Correct file permission for jack-shm-registry POSIX shared memory segment. * Checking for libsamplerate in waf, fix ticket #89." * Header cleanup, add --clients and --ports options in configure. 2008-10-01 Stephane Letz * First Solaris version. 2008-09-22 Stephane Letz * Cleanup jack_port_id_t/jack_port_t mess, should work again on 64 bits machines." 2008-09-20 Stephane Letz * Michael Voigt JackAPI cleanup patch. 2008-09-19 Stephane Letz * Michael Voigt JackTime cleanup patch. 2008-09-17 Stephane Letz * New JackDriverInfo class to cleanup driver loading code. 2008-09-08 Stephane Letz * Better symbols export for server and client side libraries. 2008-09-06 Stephane Letz * Correct driver hierarchy on macosx and windows targets. 2008-09-05 Stephane Letz * Merge Michael Voigt "drops" branch after reorganization step. 2008-09-04 Stephane Letz * Michael Voigt 4th source reorganization patch. * Correct JackNetDriver initialization. 2008-09-03 Stephane Letz * Implement DBUS entry points to handle internal clients, add new commands in jack_control. * Add new "desc" (extended description) in jack_driver_desc_t, to be used by backends and internal clients. 2008-09-01 Stephane Letz * Michael Voigt third source reorganization patch. * Add new jack_set_port_rename_callback API, jack_port_set_name is now a server request that call port rename callbacks. 2008-08-31 Stephane Letz * Michael Voigt second source reorganization patch. 2008-08-28 Stephane Letz * Michael Voigt first source reorganization patch. 2008-08-26 Stephane Letz * Better parameter handling in JackCoreAudioAdapter. * Fix memory leaks. 2008-08-23 Stephane Letz * Implements internal clients management API. 2008-08-22 Stephane Letz * Move GetCurrentTransportFrame code from JackClient to JackTransportEngine. * Add a fNetworkSync state in JackTransportEngine used in network. 2008-08-03 Stephane Letz * Fix JackFrameTimer::Time2Frames and JackTimer::Frames2Time, jack_cpu compiled again. 2008-08-01 Stephane Letz * Fix desallocation of remaining clients when server quits. * Close remaining client sockets in JackSocketServerChannel::Close. * Correct JackClient::Close() to request server close only if server is running. 2008-07-30 Stephane Letz * Remove restriction that port connection could be done only if the client was activated. 2008-07-25 Stephane Letz * Florian Faber patch for 32 bit float (LE only) support to jack's alsa driver. * Fix a crash bug when desallocating a non completely created external client. 2008-07-24 Stephane Letz * Fix server client OSX special notification mechanism, CoreAudio driver compilation back for 10.4. 2008-07-18 Stephane Letz * Correct audioadapter when a sample rate value different from jack server one is chosen. * Cleanup in JackTransportEngine, move some code that was in JackClient class. * Remove transport_type.h file, move transport types in types.h file. 2008-07-12 Stephane Letz * Loopback driver working again. 2008-07-08 Stephane Letz * Add jack_get_descriptor in internal clients API. * Fix JackFreewheelDriver::Process() in case if client time-out: continue processing until a better recovery strategy is chosen. 2008-07-08 Stephane Letz * Merge windows branch back to trunk. 2008-07-05 Stephane Letz * Netioadapter renamed in audioadapter. 2008-07-04 Stephane Letz * Netioadapter now adapts for buffer size and sample rate changes. 2008-07-03 Stephane Letz * Add IsFixedBufferSize method in all drivers. 2008-07-02 Stephane Letz * New netioadapter in server client. 2008-06-20 Stephane Letz * Add new jack_client_stop_thread and jack_client_kill_thread API. * New generic BuildClientPath for internal clients loading. 2008-06-19 Stephane Letz * Embed JackEngineControl in JackDriver (starting from Tim Blechmann idea). 2008-06-18 Stephane Letz * On OSX waf now compiles Universal Binaries. 2008-06-17 Stephane Letz * Driver class hierarchy simplification. * Update waf for compilation on OSX. 2008-06-13 Stephane Letz * Correct JackPosixThread::ThreadHandler termination, do not set buffer size if same value is used. * Another Tim Blechmann cleanup patch + do no allocate JackClientControl in shared memory for server internal clients. 2008-06-12 Stephane Letz * Another Tim Blechmann patch to remove unnecessary virtual methods. 2008-06-09 Stephane Letz * Improve net driver so that jack clients can be registered even if driver has not yet started. 2008-06-08 Stephane Letz * Add a missing EXPORT for JackException class. 2008-06-06 Stephane Letz * Better error checking in JackGraphManager::RemoveAllPorts. 2008-06-05 Stephane Letz * Better control of exported symbols. * Fix a bug in backend parameter parsing. 2008-06-04 Stephane Letz * Merge of network branch. * Use of set_threaded_log_function only when needed in RT threads. 2008-06-02 Stephane Letz * Tim Blechmann patch to remove unnecessary virtual methods: choice of the appropriate platform version is now done at compilation time. 2008-06-02 Stephane Letz * Cleanup and correct wscript for example-clients. * Add a test for coherent freewheel state in JackDebugClient. * Cleanup JackMutex class. 2008-05-31 Stephane Letz * Add missing include for proper compilation when jack headers are not installed. 2008-05-30 Stephane Letz * Avoid using Terminate when "quitting" in RT thread. Cleanup JackEngineInterface. 2008-05-29 Stephane Letz * Tim Blechmann patch for JackPosixSemaphore (still to test...). * Correct JackWinThread::Terminate. 2008-05-28 Stephane Letz * New testMutex test, correct timing in drivers. 2008-05-27 Stephane Letz * Correct timing in drivers: frame time has to be incremented before Read. 2008-05-26 Stephane Letz * Merge control branch. * Cleanup example clients: use jack_client_open and install a proper 'quit' signal handler. 2008-05-24 Stephane Letz * Tim Blechmann RAII idiom patch for JackServer ressource initialization. 2008-05-23 Stephane Letz * Use StartSync to start the client notification thread, otherwise initial notifications from the server may be lost. * Tim Blechmann JackEngine cleanup patch. * Call init callback in notification thread also. 2008-05-22 Stephane Letz * Correct JackPort::ClearBuffer. * Correct JackEngine inheritance graph. 2008-05-21 Stephane Letz * Correct JackEngine::PortUnRegister, JackEngine::ClientCloseAux and JackEngine::ClientDeactivate to correctly send notifications. * New jack_get_client_pid API, implemented on server side. * Better handling of graph state read functions: never wait when used in the real-time thread, current state is used. 2008-05-20 Stephane Letz * Package number bumped to 1.90 everywhere. * Implementation of jack_get_max_delayed_usecs, jack_get_xrun_delayed_usecs and jack_reset_max_delayed_usecs. 2008-05-19 Stephane Letz * Use of placement new for dynamic port allocation is possibly not safe... so avoid that until a definitive answer is found. * JackAudioDriver::ProcessAsync and JackAudioDriver::ProcessSync were broken at some point: 0 has to be returned in all cases. 2008-05-16 Stephane Letz * Activate now connect to FW driver and start the realtime thread only if clients are actually realtime, that is have setup any of the RT callback. 2008-05-14 Stephane Letz * Fix JackEngine::Close to only delete "loadable" clients. 2008-05-13 Stephane Letz * Fix exception handling in JackShmMem::operator new. * Fix JackMutex constructor. 2008-05-12 Stephane Letz * Allows wrapper library to log in a file (using JACK_WRAPPER_DEBUG=file). 2008-05-09 Stephane Letz * Mike Taht's fix for proper alsa xrun duration measurement. 2008-05-06 Stephane Letz * Fix JackPosixThread::StartImp and JackWinThread::StartImp. 2008-05-05 Stephane Letz * Fix JackClient::Close: notification channel is stopped first to avoid receiving notifications while closing and Close is again a synchronous call. * No more remaining client close in JackEngine::Close(). 2008-05-01 Stephane Letz * Fix JackMachClientChannel::InternalClientLoad. * Correct internal client loading. * For threaded drivers, AcquireRealTime is called after Init step. 2008-04-30 Stephane Letz * Fix JackRestartThreadedDriver::Execute. * Better handling of init and run state in JackThread. 2008-04-28 Stephane Letz * Add exceptions management to distinguish drivers recoverable errors from non recoverable ones. Will be used in special threaded drivers (for network). 2008-04-25 Stephane Letz * Correct JackServerGlobals::Init: now check is server is already started. 2008-04-24 Stephane Letz * Correct internal client load. 2008-04-10 Stephane Letz * Remove Linux Makefile, update Readme. 2008-04-03 Stephane Letz * Correct a dirty port array issue in JackGraphManager::GetPortsAux. 2008-03-31 Stephane Letz * New SetNonBlocking method for JackSocket. 2008-03-29 Stephane Letz * Correct a missing parameter in the usage message of jack_midiseq. * Add a client counter in wrapper layer: library is unloaded only when all clients have been closed. 2008-03-28 Stephane Letz * Correct PortRegister, port name checking must be done on server side. * Add an Init method for blocking drivers to be decorated using JackThreadedDriver class. 2008-03-27 Stephane Letz * Pieter Palmers patch for FFADO driver. * Dmitry Baikov patch for alsa_rawmidi driver. 2008-03-26 Stephane Letz * JackWrapperAPI.cpp: use open_library in jack_client_name_size, jack_port_name_size and jack_port_type_size. 2008-03-20 Stephane Letz * Transport timebase fix. 2008-03-19 Stephane Letz * Synchronise transport.h with latest jackd version (Video handling). 2008-03-19 Stephane Letz * Add jack_port_type_id in jack API. 2008-03-17 Stephane Letz * New jack_server_control client to test notifications when linked to the server library. * Correct JackClient::Activate so that first kGraphOrderCallback can be received by the client notification thread. * MIDI API in wrapper lib. * Fix connect notification to deliver *one* notification only. 2008-03-16 Stephane Letz * Use engine in JackAlsaDriver::port_register and JackAlsaDriver::port_unregister. * New JackLockedEngine decorator class to serialize access from ALSA Midi thread, command thread and in-server clients. 2008-03-15 Stephane Letz * Add -L (extra output latency in aynchronous mode) in CoreAudio driver. * RT scheduling for OSX thread (when use in dummy driver). 2008-03-14 Stephane Letz * Fernando Lopez-Lezcano scons patch. 2008-03-13 Stephane Letz * Add test for jack_cycle_wait, jack_cycle_wait and jack_set_process_thread API. * Add jack_set_process_thread in wrapper library. * Correct all backend playback port latency in case of "asynchronous" mode (1 buffer more). * Correct jack_port_get_total_latency. * Correct jack_port_by_id in wrapper library. 2008-03-12 Stephane Letz * Marc-Olivier Barre library related scons patch. * Nedko Arnaudov FULL_MIMIC patch. * Automatic server launch in wrapper layer. 2008-03-11 Stephane Letz * Fix engine real-time notification (was broken since ??). * Correct jack_client_open_aux, jack_client_open and jack_client_new. * Correct jack_internal_client_load for wrapper layer. * In thread model, execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished). * Correct jack_port_get_connections function (should return NULL when no connections). 2008-03-10 Stephane Letz * Nedko Arnaudov log patch. * Remove unneeded jack_port_connect API. 2008-03-07 Stephane Letz * Define an internal jack_client_open_aux needed for library wrapper feature. * Improve wrapper code. * Correct FreeBob driver_initialize. 2008-03-06 Stephane Letz * Marc-Olivier Barre scons patch (3). 2008-03-06 Stephane Letz * Fix JackSocketClientChannel::ClientClose: async call from the client and server does not need to write any reply. * Correct port notification: 2 notifications have to be sent (src, dst) and (dst, src)... 2008-03-05 Stephane Letz * libjackdmp.so renamed to libjackservermp.so and same for OSX framework. * tw1.c example added (new thread model). * Marc-Olivier Barre scons patch (2). 2008-03-02 Stephane Letz * Correct JackSocketClientChannel::ClientClose to use ServerSyncCall instead of ServerAsyncCall. * Better documentation in jack.h. * Marc-Olivier Barre scons patch. 2008-03-02 Stephane Letz * Correct jack_get_time propotype. 2008-02-25 Stephane Letz * Add TimeCallback in JackDebugClient class. 2008-02-22 Stephane Letz * Correct JACK_port_unregister. 2008-02-21 Stephane Letz * Add port register/unregister notification in JackAlsaDriver. 2008-02-12 Stephane Letz * Fix in JackClient::Error(): when RT thread is failing and calling Shutdown, Shutdown was not desactivating the client correctly. * Notify ports unregistration in JackEngine::ClientCloseAux. * Thanks Esben Stien for helping finding these bugs. 2008-02-11 Stephane Letz * Use SetAlias for port naming. Use jackd midi port naming scheme. 2008-02-08 Stephane Letz * More robust external API. 2008-02-07 Stephane Letz * Correct "server_connect": close the communication channel. 2008-02-05 Stephane Letz * Reduce WaitGraphChange wait value. * Remove use of assert in JackFifo, JackMachSemaphore, and JackPosixSemaphore: print an error instead. 2008-02-03 Stephane Letz * Add "Readme" file from package in src folder. * Tim Blechmann sse optimization patch for JackaudioPort::MixAudioBuffer, use of Apple Accelerate framework on OSX. 2008-02-02 Stephane Letz * Tim Blechmann patches. 2008-02-01 Stephane Letz * Move transport related methods from JackEngine to JackServer. * Finish port connection callback server side implementation. 2008-01-31 Stephane Letz * Remove checking thread in CoreAudio driver, better device state change recovery strategy: the driver is stopped and restarted. * jack_thread_wait implementation. * Add jack_thread_wait client example. * Add jack_mp_thread_wait client example. 2008-01-30 Stephane Letz * Latest jack_lsp code from jack SVN. * Update in usx2y.c and JackPort.cpp to match jackd 0.109.2. 2008-01-29 Stephane Letz * Implement jack_recompute_total_latency and jack_recompute_total_latencies. * Remove fBufferSize field in JackGraphManager object. * Port connection callback, client side. 2008-01-28 Stephane Letz * Updated API to match jack 0.109.0 version (in progress). Correct checking thread in CoreAudio driver. * Port connection callback, server side. * Cleanup jack_port_connected_to implementation. 2008-01-25 Stephane Letz * OSX 32/64 bits version. 2008-01-24 Stephane Letz * CoreAudio driver improvement: detect and notify abnormal situations (stopped driver in case of SR change...). 2008-01-03 Stephane Letz * Dmitry Baikov MIDI patch: alsa_seqmidi and alsa_rammidi drivers. 2008-01-03 Stephane Letz * Tim Blechmann patch for JackGraphManager::GetPortsAux memory leak, Tim Blechmann patch for scons install. 2007-12-12 Stephane Letz * Cleanup in CoreAudio driver. 2007-12-11 Stephane Letz * Change string management for proper compilation with gcc 4.2.2. JackLog cleanup. 2007-12-08 Stephane Letz * Tim Blechmann scons patch. 2007-12-07 Stephane Letz * Pieter Palmers second new build system: scons and Makefile based build. 2007-12-06 Stephane Letz * Pieter Palmers FFADO driver and scons based build. 2007-12-05 Stephane Letz * Correct sample_rate management in JackCoreAudioDriver::Open. Better handling in sample_rate change listener. 2007-12-04 Stephane Letz * Add a sample_rate change listener in CoreAudio driver. 2007-12-03 Stephane Letz * Correct bug in CoreAudio driver sample rate management. 2007-11-30 Stephane Letz * Correct JackMachNotifyChannel::ClientNotify. 2007-11-29 Stephane Letz * Correct fPeriodUsecs computation in JackAudioDriver::SetBufferSize and JackAudioDriver::SetSampleRate. 2007-11-28 Stephane Letz * On OSX, use jack server name in notification system. 2007-11-21 Stephane Letz * On OSX, use CFNotificationCenterPostNotificationWithOptions with kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions for server ==> JackRouter plugin notification. 2007-11-20 Stephane Letz * Correct CheckPort in JackAPI.cpp. 2007-11-15 Stephane Letz * Move OSX start/stop notification mechanism in Jackdmp.cpp. 2007-11-05 Stephane Letz * Use of JackWinSemaphore instead of JackWinEvent for inter-process synchronization. * Correct types.h for use with MINGW on Windows. 2007-11-04 Stephane Letz * Add an implementation for obsolete jack_internal_client_new and jack_internal_client_close. Add missing jack_port_type_size. 2007-11-02 Stephane Letz * Correct ALSA driver Attach method: internal driver may have changed the buffer_size and sample_rate values. * Add JackWinSemaphore class. 2007-10-01 Stephane Letz * Server and user directory related code moved in a JackTools file. * Client name rewritting to remove path characters (used in fifo naming). 2007-10-30 Stephane Letz * Fix a bug in freewheel management in async mode: drivers now receive the kStartFreewheelCallback and kStopFreewheelCallback notifications. 2007-10-26 Stephane Letz * Add midiseq and midisine examples. * Cleanup old zombification code. * Linux Makefile now install jack headers. * Use of JACK_CLIENT_DEBUG environment variable to activate debug client mode. * Definition of JACK_LOCATION variable using -D in the Makefile. * Restore jack 0.103.0 MIDI API version. 2007-10-25 Stephane Letz * Merge of Dmitry Baikov MIDI branch. * Correct JackGraphManager::GetPortsAux to use port type. * Remove JackEngineTiming class: code moved in JackEngineControl. 2007-10-24 Stephane Letz * Implementation of server_name setting (-n). 2007-10-23 Stephane Letz * Correct jack_acquire_real_time_scheduling on OSX. 2007-10-18 Stephane Letz * Use LIB_DIR variable for 64 bits related compilation (drivers location). More generic Linux script. 2007-10-16 Stephane Letz * Reorganize jack headers. Improve Linux install/remove scripts. 2007-10-16 Stephane Letz * Internal loadable client implementation, winpipe version added. 2007-10-12 Stephane Letz * Internal loadable client implementation, socket version added. * Fix JackEngine::Close() method. 2007-10-11 Stephane Letz * Internal loadable client implementation (in progress). 2007-10-08 Stephane Letz * Use .jackdrc file (instead of .jackdmprc). Install script now creates a link "jackd ==> jackdmp" so that automatic launch can work correctly. * Paul Davis patch for -r (--replace-registry) feature. 2007-10-07 Stephane Letz * Add missing timestamps.c and timestamps.h files. Correctly export public headers in OSX frameworks. Suppress JackEngine::ClientInternalCloseIm method. 2007-10-04 Stephane Letz * Correct "jack_register_server" in shm.c. 2007-10-04 Stephane Letz * Fix a resource leak issue in JackCoreAudioDriver::Close(). Better implement "jack_client_open" when linking a client with the server library. 2007-10-03 Stephane Letz * Rename server_name from "default" to "jackdmp_default" to avoid conflict with regular jackd server. 2007-10-02 Stephane Letz * Correct jack_client_open "status" management. 2007-08-27 Stephane Letz * Server/library protocol checking implementation. 2007-08-26 Stephane Letz * Make "Rename" a method of JackPort class, call it from driver Attach method. 2007-08-24 Stephane Letz * Implement server temporary (-T) mode. 2007-08-23 Stephane Letz * Fix a bug in jack_test. Correct JackShmMem destructor. Correct end case in JackClient::Execute. Correct JackMachSemaphore::Disconnect. 2007-08-22 Stephane Letz * Fix a bug in JackLibClient::Open introduced when adding automatic client renaming. 2007-08-21 Stephane Letz * Fix backend port alias management (renaming in system:xxx). 2007-08-20 Stephane Letz * Automatic server launch. Removes unneeded 'volatile' for JackTransportEngine::fWriteCounter. 2007-08-19 Stephane Letz * Add "systemic" latencies management in CoreAudio driver. 2007-08-16 Stephane Letz * Automatic client renaming. 2007-07-27 Stephane Letz * Correct JackEngine::ClientCloseAux (when called from JackEngine::ClientExternalOpen). Correct JackWinEvent::Allocate. 2007-07-20 Stephane Letz * Correct notification for kActivateClient event. 2007-06-11 Stephane Letz * Dmitry Baikov buffer size patch. 2007-06-10 Stephane Letz * Correct deprecated jack_set_sample_rate_callback to return 0 instead of -1. 2007-06-09 Stephane Letz * Checking in the server to avoid calling the clients if no callback are registered. 2007-06-08 Stephane Letz * New JackNotication.h header in preparation for callback checking in the server. 2007-05-29 Stephane Letz * Add "callback exiting" and "jack_frame_time" tests in jack_test. 2007-05-09 Stephane Letz * Add a mutex in JackGraphManager AllocatePort/ReleasePort methods. 2007-05-05 Stephane Letz * Add jack_set_client_registration_callback API. 2007-05-04 Stephane Letz * Steven Chamberlain patch to fix jack_port_type. Test for jack_port_type behaviour in jack_test.cpp tool. 2007-05-03 Stephane Letz * Steven Chamberlain patch to fix jack_port_by_id export. 2007-04-28 Stephane Letz * Add new jack_port_set_alias, jack_port_unset_alias and jack_port_get_aliases API. 2007-04-27 Stephane Letz * Add missing -D__SMP__in OSX project. 2007-04-23 Stephane Letz * Dmitry Baikov jackmp-time patch: add jack_get_time, jack_time_to_frames, jack_frames_to_time. 2007-04-03 Stephane Letz * Dmitry Baikov remove-nframes patch. 2007-04-02 Stephane Letz * Dmitry Baikov lost-event patch. 2007-04-01 Stephane Letz * Merge JackGraphManager Remove and Release method in a unique Release method. 2007-03-12 Stephane Letz * Bug fix in JackMidiBuffer::MaxEventSize(). 2007-03-09 Stephane Letz * Dmitry Baikov MIDI patch phase 2. 2007-03-08 Stephane Letz * Dmitry Baikov jackmp-port-clear patch. 2007-03-06 Stephane Letz * Dmitry Baikov MIDI patch phase 1. 2007-03-04 Stephane Letz * Dmitry Baikov patch for JackGraphManager.cpp. * Dmitry Baikov MIDI patch phase 0. 2007-02-19 Stephane Letz * Correct back JackAlsaDriver::Read method. 2007-02-14 Stephane Letz * Better error checking in PortAudio driver. 2007-02-07 Stephane Letz * Thom Johansen fix for port buffer alignment issues. 2007-02-05 Stephane Letz * Add Pieter Palmers FreeBob driver. * Thibault LeMeur ALSA driver patch. 2007-01-31 Stephane Letz * Use pthread_attr_setstacksize in JackPosixThread class. 2007-01-30 Stephane Letz * New LockAllMemory and UnlockAllMemory functions. 2007-01-29 Stephane Letz * More robust activation/deactivation code, especially in case of client crash. 2007-01-27 Stephane Letz * Uses a time out value of 10 sec in freewheel mode (like jack). 2007-01-21 Stephane Letz * More client debug code: check if the client is still valid in every JackDebugClient method, check if the library context is still valid in every API call. 2007-01-14 Stephane Letz * Implement thread.h API. 2007-01-09 Stephane Letz * New server/client data transfer model to fix a 64 bits system bug. Fix a device name reversal bug in ALSA driver. 2007-01-04 Stephane Letz * Add call to the init callback (set up using the jack_set_thread_init_callback API) in Real-Time and Notification threads. Define a new 'kActivateClient' notification. 2007-01-02 Stephane Letz * Internal cleanup. 2006-12-23 Stephane Letz * shared_ports renamed to shared_graph. 2006-12-15 Stephane Letz * Move client refnum management in JackEngine. 2006-12-12 Stephane Letz * Tom Szilagyi memory leak fix in ringbuffer.c. 2006-11-29 Stephane Letz * Correct JackWinEnvent::Allocate (handle the ERROR_ALREADY_EXISTS case). Correct JackEngine::ClientExternalNew. * Karsten Wiese correction for ALSA usx2y driver. 2006-11-22 Stephane Letz * In synchronous mode, if the driver time out is reached, the server may get desynchronized (pending signal may arrive in later cycles), improve audio driver synchronous code to better handle this case. 2006-11-08 Stephane Letz * Synchronize ALSA backend with jack one. 2006-11-04 Stephane Letz * Use -D to setup ADDON_DIR on OSX and Linux. 2006-10-11 Stephane Letz * Correct server SetBufferSize in case of failure. Correct PortAudio driver help. 2006-10-06 Stephane Letz * Add a new cpu testing/loading client. 2006-09-23 Stephane Letz * Rename global "verbose" in "jack_verbose" to avoid symbol clash with PureData. 2006-09-20 Stephane Letz * On Windows, avoid to use the unsafe Kill thread method. Use thread Stop instead and have blocked IO be unlocked. * Still get RT thread termination problems, restore a version that works on OSX and Linux with conditionnal compilation for now. 2006-09-16 Stephane Letz * Restore behaviour of LoopBack driver, which has to be opened in any case... 2006-09-15 Stephane Letz * On Windows version, use signal to quit the server. 2006-09-13 Stephane Letz * Correct pipe destruction bug in JackWinNamedPipe class. 2006-09-11 Stephane Letz * Handling of LoopBack driver only when really needed. * Correct crash bug when closing clients on Windows due to multi-threading synchronization issues. 2006-09-06 Stephane Letz * Correct coreaudio driver (input was not working since 0.55 version). * Version for 0.58 release. 2006-09-04 Stephane Letz * Correct Windows VC++ projects. 2006-09-03 Stephane Letz * First import of version 0.58 base code 1.9.12~dfsg/wscript0000644000000000000000000012145113214314510012762 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 from __future__ import print_function import os import subprocess import shutil import re import sys from waflib import Logs, Options, Task, Utils from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext VERSION='1.9.12' APPNAME='jack' JACK_API_VERSION = '0.1.0' # these variables are mandatory ('/' are converted automatically) top = '.' out = 'build' # lib32 variant name used when building in mixed mode lib32 = 'lib32' auto_options = [] def display_feature(conf, msg, build): if build: conf.msg(msg, 'yes', color='GREEN') else: conf.msg(msg, 'no', color='YELLOW') # This function prints an error without stopping waf. The reason waf should not # be stopped is to be able to list all missing dependencies in one chunk. def print_error(msg): print(Logs.colors.RED + msg + Logs.colors.NORMAL) class AutoOption: """ This class is the foundation for the auto options. It adds an option --foo=no|yes to the list of options and deals with all logic and checks for these options. Each option can have different dependencies that will be checked. If all dependencies are available and the user has not done any request the option will be enabled. If the user has requested to enable the option the class ensures that all dependencies are available and prints an error message otherwise. If the user disables the option, i.e. --foo=no, no checks are made. For each option it is possible to add packages that are required for the option using the add_package function. For dependency programs add_program should be used. For libraries (without pkg-config support) the add_library function should be used. For headers the add_header function exists. If there is another type of requirement or dependency the check hook (an external function called when configuring) can be used. When all checks have been made and the class has made a decision the result is saved in conf.env['NAME'] where 'NAME' by default is the uppercase of the name argument to __init__, but it can be changed with the conf_dest argument to __init__. The class will define a preprocessor symbol with the result. The default name is HAVE_NAME, but it can be changed using the define argument to __init__. """ def __init__(self, opt, name, help, conf_dest=None, define=None): # check hook to call upon configuration self.check_hook = None self.check_hook_error = None self.check_hook_found = True # required libraries self.libs = [] # elements on the form [lib,uselib_store] self.libs_not_found = [] # elements on the form lib # required headers self.headers = [] self.headers_not_found = [] # required packages (checked with pkg-config) self.packages = [] # elements on the form [package,uselib_store,atleast_version] self.packages_not_found = [] # elements on the form [package,atleast_version] # required programs self.programs = [] # elements on the form [program,var] self.programs_not_found = [] # elements on the form program # the result of the configuration (should the option be enabled or not?) self.result = False self.help = help self.option = '--' + name self.dest = 'auto_option_' + name if conf_dest: self.conf_dest = conf_dest else: self.conf_dest = name.upper() if not define: self.define = 'HAVE_' + name.upper() else: self.define = define opt.add_option(self.option, type='string', default='auto', dest=self.dest, help=self.help+' (enabled by default if possible)', metavar='no|yes') def add_library(self, library, uselib_store=None): """ Add a required library that should be checked during configuration. The library will be checked using the conf.check function. If the uselib_store arugment is not given it defaults to LIBRARY (the uppercase of the library argument). The uselib_store argument will be passed to check which means LIB_LIBRARY, CFLAGS_LIBRARY and DEFINES_LIBRARY, etc. will be defined if the option is enabled. """ if not uselib_store: uselib_store = library.upper().replace('-', '_') self.libs.append([library, uselib_store]) def add_header(self, header): """ Add a required header that should be checked during configuration. The header will be checked using the conf.check function which means HAVE_HEADER_H will be defined if found. """ self.headers.append(header) def add_package(self, package, uselib_store=None, atleast_version=None): """ Add a required package that should be checked using pkg-config during configuration. The package will be checked using the conf.check_cfg function and the uselib_store and atleast_version will be passed to check_cfg. If uselib_store is None it defaults to PACKAGE (uppercase of the package argument) with hyphens and dots replaced with underscores. If atleast_version is None it defaults to '0'. """ if not uselib_store: uselib_store = package.upper().replace('-', '_').replace('.', '_') if not atleast_version: atleast_version = '0' self.packages.append([package, uselib_store, atleast_version]) def add_program(self, program, var=None): """ Add a required program that should be checked during configuration. If var is not given it defaults to PROGRAM (the uppercase of the program argument). If the option is enabled the program is saved as a list (?!) in conf.env['PROGRAM']. """ if not var: var = program.upper().replace('-', '_') self.programs.append([program, var]) def set_check_hook(self, check_hook, check_hook_error): """ Set the check hook and the corresponding error printing function to the configure step. The check_hook argument is a function that should return True if the extra prerequisites were found and False if not. The check_hook_error argument is an error printing function that should print an error message telling the user that --foo was explicitly requested but cannot be built since the extra prerequisites were not found. Both function should take a single argument that is the waf configuration context. """ self.check_hook = check_hook self.check_hook_error = check_hook_error def _check(self, conf): """ This is an internal function that runs all necessary configure checks. It checks all dependencies (even if some dependency was not found) so that the user can install all missing dependencies in one go, instead of playing the infamous hit-configure-hit-configure game. This function returns True if all dependencies were found and False if not. """ all_found = True # Use-variables that should be used when checking libraries, headers and # programs. The list will be populated when looking for packages. use = [] # check for packages for package,uselib_store,atleast_version in self.packages: try: conf.check_cfg(package=package, uselib_store=uselib_store, atleast_version=atleast_version, args='--cflags --libs') use.append(uselib_store) except conf.errors.ConfigurationError: all_found = False self.packages_not_found.append([package,atleast_version]) # check for libraries for lib,uselib_store in self.libs: try: conf.check(lib=lib, uselib_store=uselib_store, use=use) except conf.errors.ConfigurationError: all_found = False self.libs_not_found.append(lib) # check for headers for header in self.headers: try: conf.check(header_name=header, use=use) except conf.errors.ConfigurationError: all_found = False self.headers_not_found.append(header) # check for programs for program,var in self.programs: try: conf.find_program(program, var=var, use=use) except conf.errors.ConfigurationError: all_found = False self.programs_not_found.append(program) # call hook (if specified) if self.check_hook: self.check_hook_found = self.check_hook(conf) if not self.check_hook_found: all_found = False return all_found def _configure_error(self, conf): """ This is an internal function that prints errors for each missing dependency. The error messages tell the user that this option required some dependency, but it cannot be found. """ for lib in self.libs_not_found: print_error('%s requires the %s library, but it cannot be found.' % (self.option, lib)) for header in self.headers_not_found: print_error('%s requires the %s header, but it cannot be found.' % (self.option, header)) for package,atleast_version in self.packages_not_found: string = package if atleast_version: string += ' >= ' + atleast_version print_error('%s requires the package %s, but it cannot be found.' % (self.option, string)) for program in self.programs_not_found: print_error('%s requires the %s program, but it cannot be found.' % (self.option, program)) if not self.check_hook_found: self.check_hook_error(conf) def configure(self, conf): """ This function configures the option examining the argument given too --foo (where foo is this option). This function sets self.result to the result of the configuration; True if the option should be enabled or False if not. If not all dependencies were found self.result will shall be False. conf.env['NAME'] will be set to the same value aswell as a preprocessor symbol will be defined according to the result. If --foo[=yes] was given, but some dependency was not found an error message is printed (foreach missing dependency). This function returns True on success and False on error. """ argument = getattr(Options.options, self.dest) if argument == 'no': self.result = False retvalue = True elif argument == 'yes': if self._check(conf): self.result = True retvalue = True else: self.result = False retvalue = False self._configure_error(conf) elif argument == 'auto': self.result = self._check(conf) retvalue = True else: print_error('Invalid argument "' + argument + '" to ' + self.option) self.result = False retvalue = False conf.env[self.conf_dest] = self.result if self.result: conf.define(self.define, 1) else: conf.define(self.define, 0) return retvalue def display_message(self, conf): """ This function displays a result message with the help text and the result of the configuration. """ display_feature(conf, self.help, self.result) # This function adds an option to the list of auto options and returns the newly # created option. def add_auto_option(opt, name, help, conf_dest=None, define=None): option = AutoOption(opt, name, help, conf_dest=conf_dest, define=define) auto_options.append(option) return option # This function applies a hack that for each auto option --foo=no|yes replaces # any occurence --foo in argv with --foo=yes, in effect interpreting --foo as # --foo=yes. The function has to be called before waf issues the option parser, # i.e. before the configure phase. def auto_options_argv_hack(): for option in auto_options: for x in range(1, len(sys.argv)): if sys.argv[x] == option.option: sys.argv[x] += '=yes' # This function configures all auto options. It stops waf and prints an error # message if there were unsatisfied requirements. def configure_auto_options(conf): ok = True for option in auto_options: if not option.configure(conf): ok = False if not ok: conf.fatal('There were unsatisfied requirements.') # This function displays all options and the configuration results. def display_auto_options_messages(conf): for option in auto_options: option.display_message(conf) def check_for_celt(conf): found = False for version in ['11', '8', '7', '5']: define = 'HAVE_CELT_API_0_' + version if not found: try: conf.check_cfg(package='celt', atleast_version='0.' + version + '.0', args='--cflags --libs') found = True conf.define(define, 1) continue except conf.errors.ConfigurationError: pass conf.define(define, 0) return found def check_for_celt_error(conf): print_error('--celt requires the package celt, but it could not be found.') # The readline/readline.h header does not work if stdio.h is not included # before. Thus a fragment with both stdio.h and readline/readline.h need to be # test-compiled to find out whether readline is available. def check_for_readline(conf): # FIXME: This check can be incorporated into the AutoOptions class by # passing header_name=['stdio.h', 'readline/readline.h'] to check. try: conf.check(fragment=''' #include #include int main(void) { return 0; }''', execute=False, msg='Checking for header readline/readline.h', errmsg='not found') return True except conf.errors.ConfigurationError: return False def check_for_readline_error(conf): print_error('--readline requires the readline/readline.h header, but it cannot be found.') def check_for_mmsystem(conf): # FIXME: See comment in check_for_readline. try: conf.check(fragment=''' #include #include int main(void) { return 0; }''', execute=False, msg='Checking for header mmsystem.h', errmsg='not found') return True except conf.errors.ConfigurationError: return False def check_for_mmsystem_error(conf): print_error('--winmme requires the mmsystem.h header, but it cannot be found.') def options(opt): # options provided by the modules opt.load('compiler_cxx') opt.load('compiler_c') opt.load('xcode') opt.load('xcode6') # install directories opt.add_option('--htmldir', type='string', default=None, help='HTML documentation directory [Default: /share/jack-audio-connection-kit/reference/html/') opt.add_option('--libdir', type='string', help='Library directory [Default: /lib]') opt.add_option('--libdir32', type='string', help='32bit Library directory [Default: /lib32]') opt.add_option('--mandir', type='string', help='Manpage directory [Default: /share/man/man1]') # options affecting binaries opt.add_option('--platform', type='string', default=sys.platform, help='Target platform for cross-compiling, e.g. cygwin or win32') opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--debug', action='store_true', default=False, dest='debug', help='Build debuggable binaries') # options affecting general jack functionality opt.add_option('--classic', action='store_true', default=False, help='Force enable standard JACK (jackd) even if D-Bus JACK (jackdbus) is enabled too') opt.add_option('--dbus', action='store_true', default=False, help='Enable D-Bus JACK (jackdbus)') opt.add_option('--autostart', type='string', default='default', help='Autostart method. Possible values: "default", "classic", "dbus", "none"') opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') opt.add_option('--clients', default=64, type='int', dest='clients', help='Maximum number of JACK clients') opt.add_option('--ports-per-application', default=768, type='int', dest='application_ports', help='Maximum number of ports per application') # options with third party dependencies doxygen = add_auto_option(opt, 'doxygen', help='Build doxygen documentation', conf_dest='BUILD_DOXYGEN_DOCS') doxygen.add_program('doxygen') alsa = add_auto_option(opt, 'alsa', help='Enable ALSA driver', conf_dest='BUILD_DRIVER_ALSA') alsa.add_package('alsa', atleast_version='1.0.18') firewire = add_auto_option(opt, 'firewire', help='Enable FireWire driver (FFADO)', conf_dest='BUILD_DRIVER_FFADO') firewire.add_package('libffado', atleast_version='1.999.17') freebob = add_auto_option(opt, 'freebob', help='Enable FreeBob driver') freebob.add_package('libfreebob', atleast_version='1.0.0') iio = add_auto_option(opt, 'iio', help='Enable IIO driver', conf_dest='BUILD_DRIVER_IIO') iio.add_package('gtkIOStream', atleast_version='1.4.0') iio.add_package('eigen3', atleast_version='3.1.2') portaudio = add_auto_option(opt, 'portaudio', help='Enable Portaudio driver', conf_dest='BUILD_DRIVER_PORTAUDIO') portaudio.add_header('windows.h') # only build portaudio on windows portaudio.add_package('portaudio-2.0', uselib_store='PORTAUDIO', atleast_version='19') winmme = add_auto_option(opt, 'winmme', help='Enable WinMME driver', conf_dest='BUILD_DRIVER_WINMME') winmme.set_check_hook(check_for_mmsystem, check_for_mmsystem_error) celt = add_auto_option(opt, 'celt', help='Build with CELT') celt.set_check_hook(check_for_celt, check_for_celt_error) opus = add_auto_option(opt, 'opus', help='Build Opus netjack2') opus.add_header('opus/opus_custom.h') opus.add_package('opus', atleast_version='0.9.0') samplerate = add_auto_option(opt, 'samplerate', help='Build with libsamplerate') samplerate.add_package('samplerate') sndfile = add_auto_option(opt, 'sndfile', help='Build with libsndfile') sndfile.add_package('sndfile') readline = add_auto_option(opt, 'readline', help='Build with readline') readline.add_library('readline') readline.set_check_hook(check_for_readline, check_for_readline_error) # dbus options opt.recurse('dbus') # this must be called before the configure phase auto_options_argv_hack() def detect_platform(conf): # GNU/kFreeBSD and GNU/Hurd are treated as Linux platforms = [ # ('KEY, 'Human readable name', ['strings', 'to', 'check', 'for']) ('IS_LINUX', 'Linux', ['gnu0', 'gnukfreebsd', 'linux', 'posix']), ('IS_MACOSX', 'MacOS X', ['darwin']), ('IS_SUN', 'SunOS', ['sunos']), ('IS_WINDOWS', 'Windows', ['cygwin', 'msys', 'win32']) ] for key,name,strings in platforms: conf.env[key] = False conf.start_msg('Checking platform') platform = Options.options.platform for key,name,strings in platforms: for s in strings: if platform.startswith(s): conf.env[key] = True conf.end_msg(name, color='CYAN') break def configure(conf): conf.load('compiler_cxx') conf.load('compiler_c') detect_platform(conf) if conf.env['IS_WINDOWS']: conf.env.append_unique('CCDEFINES', '_POSIX') conf.env.append_unique('CXXDEFINES', '_POSIX') conf.env.append_unique('CXXFLAGS', '-Wall') conf.env.append_unique('CFLAGS', '-Wall') if conf.env['IS_MACOSX']: conf.check(lib='aften', uselib='AFTEN', define_name='AFTEN') # configure all auto options configure_auto_options(conf) # Check for functions. conf.check( function_name='ppoll', header_name=['poll.h', 'signal.h'], defines=['_GNU_SOURCE'], mandatory=False) # Check for backtrace support conf.check( header_name='execinfo.h', define_name='HAVE_EXECINFO_H', mandatory=False) conf.recurse('common') if Options.options.dbus: conf.recurse('dbus') if conf.env['BUILD_JACKDBUS'] != True: conf.fatal('jackdbus was explicitly requested but cannot be built') conf.recurse('example-clients') # test for the availability of ucontext, and how it should be used for t in ['gp_regs', 'uc_regs', 'mc_gregs', 'gregs']: fragment = '#include \n' fragment += 'int main() { ucontext_t *ucontext; return (int) ucontext->uc_mcontext.%s[0]; }' % t confvar = 'HAVE_UCONTEXT_%s' % t.upper() conf.check_cc(fragment=fragment, define_name=confvar, mandatory=False, msg='Checking for ucontext->uc_mcontext.%s' % t) if conf.is_defined(confvar): conf.define('HAVE_UCONTEXT', 1) fragment = '#include \n' fragment += 'int main() { return NGREG; }' conf.check_cc(fragment=fragment, define_name='HAVE_NGREG', mandatory=False, msg='Checking for NGREG') conf.env['LIB_PTHREAD'] = ['pthread'] conf.env['LIB_DL'] = ['dl'] conf.env['LIB_RT'] = ['rt'] conf.env['LIB_M'] = ['m'] conf.env['LIB_STDC++'] = ['stdc++'] conf.env['JACK_API_VERSION'] = JACK_API_VERSION conf.env['JACK_VERSION'] = VERSION conf.env['BUILD_WITH_PROFILE'] = Options.options.profile conf.env['BUILD_WITH_32_64'] = Options.options.mixed conf.env['BUILD_CLASSIC'] = Options.options.classic conf.env['BUILD_DEBUG'] = Options.options.debug if conf.env['BUILD_JACKDBUS']: conf.env['BUILD_JACKD'] = conf.env['BUILD_CLASSIC'] else: conf.env['BUILD_JACKD'] = True conf.env['BINDIR'] = conf.env['PREFIX'] + '/bin' if Options.options.htmldir: conf.env['HTMLDIR'] = Options.options.htmldir else: # set to None here so that the doxygen code can find out the highest # directory to remove upon install conf.env['HTMLDIR'] = None if Options.options.libdir: conf.env['LIBDIR'] = Options.options.libdir else: conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib' if Options.options.mandir: conf.env['MANDIR'] = Options.options.mandir else: conf.env['MANDIR'] = conf.env['PREFIX'] + '/share/man/man1' if conf.env['BUILD_DEBUG']: conf.env.append_unique('CXXFLAGS', '-g') conf.env.append_unique('CFLAGS', '-g') conf.env.append_unique('LINKFLAGS', '-g') if not Options.options.autostart in ['default', 'classic', 'dbus', 'none']: conf.fatal('Invalid autostart value "' + Options.options.autostart + '"') if Options.options.autostart == 'default': if conf.env['BUILD_JACKD']: conf.env['AUTOSTART_METHOD'] = 'classic' else: conf.env['AUTOSTART_METHOD'] = 'dbus' else: conf.env['AUTOSTART_METHOD'] = Options.options.autostart if conf.env['AUTOSTART_METHOD'] == 'dbus' and not conf.env['BUILD_JACKDBUS']: conf.fatal('D-Bus autostart mode was specified but jackdbus will not be built') if conf.env['AUTOSTART_METHOD'] == 'classic' and not conf.env['BUILD_JACKD']: conf.fatal('Classic autostart mode was specified but jackd will not be built') if conf.env['AUTOSTART_METHOD'] == 'dbus': conf.define('USE_LIBDBUS_AUTOLAUNCH', 1) elif conf.env['AUTOSTART_METHOD'] == 'classic': conf.define('USE_CLASSIC_AUTOLAUNCH', 1) conf.define('CLIENT_NUM', Options.options.clients) conf.define('PORT_NUM_FOR_CLIENT', Options.options.application_ports) if conf.env['IS_WINDOWS']: # we define this in the environment to maintain compatability with # existing install paths that use ADDON_DIR rather than have to # have special cases for windows each time. conf.env['ADDON_DIR'] = conf.env['BINDIR'] + '/jack' # don't define ADDON_DIR in config.h, use the default 'jack' defined in # windows/JackPlatformPlug_os.h else: conf.env['ADDON_DIR'] = os.path.normpath(os.path.join(conf.env['LIBDIR'], 'jack')) conf.define('ADDON_DIR', conf.env['ADDON_DIR']) conf.define('JACK_LOCATION', os.path.normpath(os.path.join(conf.env['PREFIX'], 'bin'))) if not conf.env['IS_WINDOWS']: conf.define('USE_POSIX_SHM', 1) conf.define('JACKMP', 1) if conf.env['BUILD_JACKDBUS']: conf.define('JACK_DBUS', 1) if conf.env['BUILD_WITH_PROFILE']: conf.define('JACK_MONITOR', 1) conf.write_config_header('config.h', remove=False) svnrev = None try: f = open('svnversion.h') data = f.read() m = re.match(r'^#define SVN_VERSION "([^"]*)"$', data) if m != None: svnrev = m.group(1) f.close() except IOError: pass if Options.options.mixed: conf.setenv(lib32, env=conf.env.derive()) conf.env.append_unique('CXXFLAGS', '-m32') conf.env.append_unique('CFLAGS', '-m32') conf.env.append_unique('LINKFLAGS', '-m32') if Options.options.libdir32: conf.env['LIBDIR'] = Options.options.libdir32 else: conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib32' conf.write_config_header('config.h') print() print('==================') version_msg = 'JACK ' + VERSION if svnrev: version_msg += ' exported from r' + svnrev else: version_msg += ' svn revision will checked and eventually updated during build' print(version_msg) conf.msg('Maximum JACK clients', Options.options.clients, color='NORMAL') conf.msg('Maximum ports per application', Options.options.application_ports, color='NORMAL') conf.msg('Install prefix', conf.env['PREFIX'], color='CYAN') conf.msg('Library directory', conf.all_envs['']['LIBDIR'], color='CYAN') if conf.env['BUILD_WITH_32_64']: conf.msg('32-bit library directory', conf.all_envs[lib32]['LIBDIR'], color='CYAN') conf.msg('Drivers directory', conf.env['ADDON_DIR'], color='CYAN') display_feature(conf, 'Build debuggable binaries', conf.env['BUILD_DEBUG']) tool_flags = [ ('C compiler flags', ['CFLAGS', 'CPPFLAGS']), ('C++ compiler flags', ['CXXFLAGS', 'CPPFLAGS']), ('Linker flags', ['LINKFLAGS', 'LDFLAGS']) ] for name,vars in tool_flags: flags = [] for var in vars: flags += conf.all_envs[''][var] conf.msg(name, repr(flags), color='NORMAL') if conf.env['BUILD_WITH_32_64']: conf.msg('32-bit C compiler flags', repr(conf.all_envs[lib32]['CFLAGS'])) conf.msg('32-bit C++ compiler flags', repr(conf.all_envs[lib32]['CXXFLAGS'])) conf.msg('32-bit linker flags', repr(conf.all_envs[lib32]['LINKFLAGS'])) display_feature(conf, 'Build with engine profiling', conf.env['BUILD_WITH_PROFILE']) display_feature(conf, 'Build with 32/64 bits mixed mode', conf.env['BUILD_WITH_32_64']) display_feature(conf, 'Build standard JACK (jackd)', conf.env['BUILD_JACKD']) display_feature(conf, 'Build D-Bus JACK (jackdbus)', conf.env['BUILD_JACKDBUS']) conf.msg('Autostart method', conf.env['AUTOSTART_METHOD']) if conf.env['BUILD_JACKDBUS'] and conf.env['BUILD_JACKD']: print(Logs.colors.RED + 'WARNING !! mixing both jackd and jackdbus may cause issues:' + Logs.colors.NORMAL) print(Logs.colors.RED + 'WARNING !! jackdbus does not use .jackdrc nor qjackctl settings' + Logs.colors.NORMAL) # display configuration result messages for auto options display_auto_options_messages(conf) if conf.env['BUILD_JACKDBUS']: conf.msg('D-Bus service install directory', conf.env['DBUS_SERVICES_DIR'], color='CYAN') if conf.env['DBUS_SERVICES_DIR'] != conf.env['DBUS_SERVICES_DIR_REAL']: print() print(Logs.colors.RED + 'WARNING: D-Bus session services directory as reported by pkg-config is') print(Logs.colors.RED + 'WARNING:', end=' ') print(Logs.colors.CYAN + conf.env['DBUS_SERVICES_DIR_REAL']) print(Logs.colors.RED + 'WARNING: but service file will be installed in') print(Logs.colors.RED + 'WARNING:', end=' ') print(Logs.colors.CYAN + conf.env['DBUS_SERVICES_DIR']) print(Logs.colors.RED + 'WARNING: You may need to adjust your D-Bus configuration after installing jackdbus') print('WARNING: You can override dbus service install directory') print('WARNING: with --enable-pkg-config-dbus-service-dir option to this script') print(Logs.colors.NORMAL, end=' ') print() def init(ctx): for y in (BuildContext, CleanContext, InstallContext, UninstallContext): name = y.__name__.replace('Context','').lower() class tmp(y): cmd = name + '_' + lib32 variant = lib32 def obj_add_includes(bld, obj): if bld.env['BUILD_JACKDBUS']: obj.includes += ['dbus'] if bld.env['IS_LINUX']: obj.includes += ['linux', 'posix'] if bld.env['IS_MACOSX']: obj.includes += ['macosx', 'posix'] if bld.env['IS_SUN']: obj.includes += ['posix', 'solaris'] if bld.env['IS_WINDOWS']: obj.includes += ['windows'] # FIXME: Is SERVER_SIDE needed? def build_jackd(bld): jackd = bld( features = ['cxx', 'cxxprogram'], defines = ['HAVE_CONFIG_H','SERVER_SIDE'], includes = ['.', 'common', 'common/jack'], target = 'jackd', source = ['common/Jackdmp.cpp'], use = ['serverlib'] ) if bld.env['BUILD_JACKDBUS']: jackd.source += ['dbus/audio_reserve.c', 'dbus/reserve.c'] jackd.use += ['DBUS-1'] if bld.env['IS_LINUX']: jackd.use += ['DL', 'M', 'PTHREAD', 'RT', 'STDC++'] if bld.env['IS_MACOSX']: jackd.use += ['DL', 'PTHREAD'] jackd.framework = ['CoreFoundation'] if bld.env['IS_SUN']: jackd.use += ['DL', 'PTHREAD'] obj_add_includes(bld, jackd) return jackd # FIXME: Is SERVER_SIDE needed? def create_driver_obj(bld, **kw): if bld.env['IS_MACOSX'] or bld.env['IS_WINDOWS']: # On MacOSX this is necessary. # I do not know if this is necessary on Windows. # Note added on 2015-12-13 by karllinden. if 'use' in kw: kw['use'] += ['serverlib'] else: kw['use'] = ['serverlib'] driver = bld( features = ['c', 'cxx', 'cshlib', 'cxxshlib'], defines = ['HAVE_CONFIG_H', 'SERVER_SIDE'], includes = ['.', 'common', 'common/jack'], install_path = '${ADDON_DIR}/', **kw) if bld.env['IS_WINDOWS']: driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' else: driver.env['cxxshlib_PATTERN'] = 'jack_%s.so' obj_add_includes(bld, driver) return driver def build_drivers(bld): # Non-hardware driver sources. Lexically sorted. dummy_src = [ 'common/JackDummyDriver.cpp' ] loopback_src = [ 'common/JackLoopbackDriver.cpp' ] net_src = [ 'common/JackNetDriver.cpp' ] netone_src = [ 'common/JackNetOneDriver.cpp', 'common/netjack.c', 'common/netjack_packet.c' ] proxy_src = [ 'common/JackProxyDriver.cpp' ] # Hardware driver sources. Lexically sorted. alsa_src = [ 'common/memops.c', 'linux/alsa/JackAlsaDriver.cpp', 'linux/alsa/alsa_rawmidi.c', 'linux/alsa/alsa_seqmidi.c', 'linux/alsa/alsa_midi_jackmp.cpp', 'linux/alsa/generic_hw.c', 'linux/alsa/hdsp.c', 'linux/alsa/alsa_driver.c', 'linux/alsa/hammerfall.c', 'linux/alsa/ice1712.c' ] alsarawmidi_src = [ 'linux/alsarawmidi/JackALSARawMidiDriver.cpp', 'linux/alsarawmidi/JackALSARawMidiInputPort.cpp', 'linux/alsarawmidi/JackALSARawMidiOutputPort.cpp', 'linux/alsarawmidi/JackALSARawMidiPort.cpp', 'linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp', 'linux/alsarawmidi/JackALSARawMidiSendQueue.cpp', 'linux/alsarawmidi/JackALSARawMidiUtil.cpp' ] boomer_src = [ 'common/memops.c', 'solaris/oss/JackBoomerDriver.cpp' ] coreaudio_src = [ 'macosx/coreaudio/JackCoreAudioDriver.mm', 'common/JackAC3Encoder.cpp' ] coremidi_src = [ 'macosx/coremidi/JackCoreMidiInputPort.mm', 'macosx/coremidi/JackCoreMidiOutputPort.mm', 'macosx/coremidi/JackCoreMidiPhysicalInputPort.mm', 'macosx/coremidi/JackCoreMidiPhysicalOutputPort.mm', 'macosx/coremidi/JackCoreMidiVirtualInputPort.mm', 'macosx/coremidi/JackCoreMidiVirtualOutputPort.mm', 'macosx/coremidi/JackCoreMidiPort.mm', 'macosx/coremidi/JackCoreMidiUtil.mm', 'macosx/coremidi/JackCoreMidiDriver.mm' ] ffado_src = [ 'linux/firewire/JackFFADODriver.cpp', 'linux/firewire/JackFFADOMidiInputPort.cpp', 'linux/firewire/JackFFADOMidiOutputPort.cpp', 'linux/firewire/JackFFADOMidiReceiveQueue.cpp', 'linux/firewire/JackFFADOMidiSendQueue.cpp' ] freebob_src = [ 'linux/freebob/JackFreebobDriver.cpp' ] iio_driver_src = [ 'linux/iio/JackIIODriver.cpp' ] oss_src = [ 'common/memops.c', 'solaris/oss/JackOSSDriver.cpp' ] portaudio_src = [ 'windows/portaudio/JackPortAudioDevices.cpp', 'windows/portaudio/JackPortAudioDriver.cpp', ] winmme_src = [ 'windows/winmme/JackWinMMEDriver.cpp', 'windows/winmme/JackWinMMEInputPort.cpp', 'windows/winmme/JackWinMMEOutputPort.cpp', 'windows/winmme/JackWinMMEPort.cpp', ] # Create non-hardware driver objects. Lexically sorted. create_driver_obj( bld, target = 'dummy', source = dummy_src) create_driver_obj( bld, target = 'loopback', source = loopback_src) create_driver_obj( bld, target = 'net', source = net_src) create_driver_obj( bld, target = 'netone', source = netone_src, use = ['SAMPLERATE', 'CELT']) create_driver_obj( bld, target = 'proxy', source = proxy_src) # Create hardware driver objects. Lexically sorted after the conditional, # e.g. BUILD_DRIVER_ALSA. if bld.env['BUILD_DRIVER_ALSA']: create_driver_obj( bld, target = 'alsa', source = alsa_src, use = ['ALSA']) create_driver_obj( bld, target = 'alsarawmidi', source = alsarawmidi_src, use = ['ALSA']) if bld.env['BUILD_DRIVER_FREEBOB']: create_driver_obj( bld, target = 'freebob', source = freebob_src, use = ['LIBFREEBOB']) if bld.env['BUILD_DRIVER_FFADO']: create_driver_obj( bld, target = 'firewire', source = ffado_src, use = ['LIBFFADO']) if bld.env['BUILD_DRIVER_IIO']: create_driver_obj( bld, target = 'iio', source = iio_src, use = ['GTKIOSTREAM', 'EIGEN3']) if bld.env['BUILD_DRIVER_PORTAUDIO']: create_driver_obj( bld, target = 'portaudio', source = portaudio_src, use = ['PORTAUDIO']) if bld.env['BUILD_DRIVER_WINMME']: create_driver_obj( bld, target = 'winmme', source = winmme_src, use = ['WINMME']) if bld.env['IS_MACOSX']: create_driver_obj( bld, target = 'coreaudio', source = coreaudio_src, use = ['AFTEN'], framework = ['AudioUnit', 'CoreAudio', 'CoreServices']) create_driver_obj( bld, target = 'coremidi', source = coremidi_src, use = ['serverlib'], # FIXME: Is this needed? framework = ['AudioUnit', 'CoreMIDI', 'CoreServices', 'Foundation']) if bld.env['IS_SUN']: create_driver_obj( bld, target = 'boomer', source = boomer_src) create_driver_obj( bld, target = 'oss', source = oss_src) def build(bld): if not bld.variant and bld.env['BUILD_WITH_32_64']: Options.commands.append(bld.cmd + '_' + lib32) # process subfolders from here bld.recurse('common') if bld.variant: # only the wscript in common/ knows how to handle variants return if not os.access('svnversion.h', os.R_OK): def post_run(self): sg = Utils.h_file(self.outputs[0].abspath(self.env)) #print sg.encode('hex') Build.bld.node_sigs[self.env.variant()][self.outputs[0].id] = sg script = bld.path.find_resource('svnversion_regenerate.sh') script = script.abspath() bld( rule = '%s ${TGT}' % script, name = 'svnversion', runnable_status = Task.RUN_ME, before = 'c cxx', color = 'BLUE', post_run = post_run, source = ['svnversion_regenerate.sh'], target = [bld.path.find_or_declare('svnversion.h')] ) if bld.env['BUILD_JACKD']: build_jackd(bld) build_drivers(bld) bld.recurse('example-clients') if bld.env['IS_LINUX']: bld.recurse('man') if not bld.env['IS_WINDOWS']: bld.recurse('tests') if bld.env['BUILD_JACKDBUS']: bld.recurse('dbus') if bld.env['BUILD_DOXYGEN_DOCS']: html_build_dir = bld.path.find_or_declare('html').abspath() bld( features = 'subst', source = 'doxyfile.in', target = 'doxyfile', HTML_BUILD_DIR = html_build_dir, SRCDIR = bld.srcnode.abspath(), VERSION = VERSION ) # There are two reasons for logging to doxygen.log and using it as # target in the build rule (rather than html_build_dir): # (1) reduce the noise when running the build # (2) waf has a regular file to check for a timestamp. If the directory # is used instead waf will rebuild the doxygen target (even upon # install). def doxygen(task): doxyfile = task.inputs[0].abspath() logfile = task.outputs[0].abspath() cmd = '%s %s &> %s' % (task.env['DOXYGEN'][0], doxyfile, logfile) return task.exec_command(cmd) bld( rule = doxygen, source = 'doxyfile', target = 'doxygen.log' ) # Determine where to install HTML documentation. Since share_dir is the # highest directory the uninstall routine should remove, there is no # better candidate for share_dir, but the requested HTML directory if # --htmldir is given. if bld.env['HTMLDIR']: html_install_dir = bld.options.destdir + bld.env['HTMLDIR'] share_dir = html_install_dir else: share_dir = bld.options.destdir + bld.env['PREFIX'] + '/share/jack-audio-connection-kit' html_install_dir = share_dir + '/reference/html/' if bld.cmd == 'install': if os.path.isdir(html_install_dir): Logs.pprint('CYAN', 'Removing old doxygen documentation installation...') shutil.rmtree(html_install_dir) Logs.pprint('CYAN', 'Removing old doxygen documentation installation done.') Logs.pprint('CYAN', 'Installing doxygen documentation...') shutil.copytree(html_build_dir, html_install_dir) Logs.pprint('CYAN', 'Installing doxygen documentation done.') elif bld.cmd =='uninstall': Logs.pprint('CYAN', 'Uninstalling doxygen documentation...') if os.path.isdir(share_dir): shutil.rmtree(share_dir) Logs.pprint('CYAN', 'Uninstalling doxygen documentation done.') elif bld.cmd =='clean': if os.access(html_build_dir, os.R_OK): Logs.pprint('CYAN', 'Removing doxygen generated documentation...') shutil.rmtree(html_build_dir) Logs.pprint('CYAN', 'Removing doxygen generated documentation done.') def dist(ctx): # This code blindly assumes it is working in the toplevel source directory. if not os.path.exists('svnversion.h'): os.system('./svnversion_regenerate.sh svnversion.h') from waflib import TaskGen @TaskGen.extension('.mm') def mm_hook(self, node): """Alias .mm files to be compiled the same as .cpp files, gcc will do the right thing.""" return self.create_compiled_task('cxx', node) 1.9.12~dfsg/README0000644000000000000000000013030413214314510012221 0ustar rootroot----------------------------------------------------------- jackdmp (aka JACK2) for Linux, MacOSX, Windows and Solaris ----------------------------------------------------------- jackdmp is a C++ version of the JACK low-latency audio server for multi-processor machines. It is a new implementation of the JACK server core features that aims in removing some limitations of the JACK1 design. The activation system has been changed for a data flow model and lock-free programming techniques for graph access have been used to have a more dynamic and robust system. - jackdmp use a new client activation model that allows simultaneous client execution (on a smp machine) when parallel clients exist in the graph (client that have the same inputs). This activation model allows to better use available CPU on a smp machine, but also works on mono-processor machine. - jackdmp use a lock-free way to access (read/write) the client graph, thus allowing connections/disconnection to be done without interrupting the audio stream. The result is that connections/disconnections are glitch-free. - jackdmp can work in 2 different modes at the server level : - synchronous activation : in a given cycle, the server waits for all clients to be finished (similar to normal jackd) - asynchronous activation : in a given cycle, the server does not wait for all clients to be finished and use output buffer computed the previous cycle. The audible result of this mode is that if a client is not activated during one cycle, other clients may still run and the resulting audio stream will still be produced (even if its partial in some way). This mode usually result in fewer (less audible) audio glitches in a loaded system. -------------- Linux version -------------- The published version still uses fifos for server/client synchronization. The use of POSIX named semaphore is implemented but still a bit unstable. Sockets are used for server/client communications. The ALSA backend derived from jackd implementation is used. To build jackdmp, a "waf" (http://code.google.com/p/waf/) based compilation system is available. The code has to be compiled on a machine where ALSA and possibly freebob (FFADO) headers and libraries are corrected installed. In the top folder do : ./waf configure ./waf build sudo ./waf install Various compilation options can be seen using ./waf --help. Important compilation options : - default compilation mode will produce a set of libraries and executable that will *replace* regular jackd. If the "automatic start server option" is used by clients, jackd server will be started using the old fork + exe system. - the --dbus flag must be defined at configure time to compile the jackdbus executable. If the "automatic start server option" is used by clients, jackd server will be started using the dbus service. ---------------------------- Known problems, limitations ---------------------------- - use of POSIX named semaphore is currently unstable and not recommended yet. ---------------- Solaris version ---------------- The published version uses fifos for server/client synchronization. Sockets are used for server/client communications. An OSS backend is used. To build jackdmp, a "waf" (http://code.google.com/p/waf/) based compilation system is available. The code has to be compiled on a machine where OSS 4.0 headers and libraries are corrected installed. In the top folder do : ./waf configure ./waf build sudo ./waf install (Note : you may have to use "pfexec" instead of "sudo" on systems where sudo is not there). Various compilation options can be seen using ./waf --help. Important compilation options : - if the "automatic start server option" is used by clients, jackd server will be started using the old fork + exe system. - the --dbus flag must be defined at configure time to compile the jackdbus executable. If the "automatic start server option" is used by clients, jackd server will be started using the dbus service. Starting the server : - for best performances, the server has to be started with privileges that allows to use "real-time" threads, for example using the "pfexec" command (or configurating the system with "priocntl" first), for instance : pfexec jackd -R -S -P59 -d oss - audio cards info can be retrieved using "ossinfo" tool (for instance ossinfo -v3). Some card needs to be configured first using "ossxmix" then the correct buffer size has to be used, for instance : pfexec jackd -R -S -P59 -d oss -p 512 ------------ OSX version ------------ The published version uses Mach semaphores for server/client synchronization. Sockets are used for server/client communications. The CoreAudio backend derived from JACK1 implementation is used. Starting with 0.70 version, the OSX project can compile 32/64 bits binaries for PPC and Intel machines. On a 64 bits machine, using the "jackdmp" in a terminal will start the 64 bits version. Using the "arch" command possibly allows to force starting in 32 bits (see man arch). The JackPilot and JackRouter binaries are now also released as 32/64 bits versions for PPC and Intel machines. By default the JackPilot application will start in 32 bits mode (even on a 64 bits machine) and launch the 32 bits jackdmp. Unchecking the "Launch in 32 bits mode" box in the JackPilot info (GetInfo = %I in the Finder...) allows to start JackPilot in 64 bits then launch the 64 bits jackdmp version. Very few audio applications are already 64 bits aware: Apple AU Lab (included in Developer tools) can be launched in 64 bit, here again by unchecking the "Launch in 32 bits mode" box in the AU Lab info. JackOSX package (found at www.jackosx.com) is the preferred way to Jackdmp on OSX. --------------------------------- Mac Intel special considerations --------------------------------- - New Mac Intel use 2 different CoreAudio device for input/output. Jackdmp cannot directly handle 2 devices to do duplex processing. An "aggregate" device has to be built in this case. Use the "/Applications/Utilities/Audio MIDI Setup" tool to build and aggregate device that combine both input and output in a single duplex device, then select it when launching jackdmp, with something like : jackdmp -R -d coreaudio -n "~:Aggregate:0" or directly with the JackPilot tool. Starting from 1.9.6 version, the CoreAudio diver can now dynamically aggregate devices. So using "Audio MIDI Setup" tool is not mandatory anymore. - CoreAudio applications running under Rosetta emulator cannot access an Intel version of Jackdmp. Using jackdmp with QjackCtl : To start jackdmp server in QjackCtl, the complete server path has to be added, like /usr/local/bin/jackdmp in Setup/Server Path. ---------------- Windows version ---------------- The published version uses named event for server/client synchronization. Named pipes are used for server/client communications. A PortAudio (V19) based driver is used. It allows to access either MME, DirectSound or ASIO supported cards. To cross compile using mingw, do the following in the top folder: ARCH=x86_64-w64-mingw32.shared # e.g. PKGCONFIG=$ARCH-pkg-config CC=$ARCH-gcc CXX=$ARCH-g++ ./waf configure --platform=win32 PKGCONFIG=$ARCH-pkg-config CC=$ARCH-gcc CXX=$ARCH-g++ ./waf build -v The binary elements are : - jackd.exe : the JACK server - libjackserver.dll (and associated libjackserver.lib library) : the server code, shared by the jackdmp server and drivers. - libjack.dll (and associated libjack.lib library) : the jack library code, to be linked against by clients. - jack_portaudio.dll : the PortAudio based backend. The backend components (currently "jack_portaudio.dll" only) are searched for in a "jackmp" folder located with the "jackdmp.exe" server. - jack_dummy.dll : the "dummy" driver. - jack_net.dll : the NetJack2 driver. - jack_netone.dll : the NetJack1 driver. - netmanager.dll : the "in server" client NetJack Manager. - audioadapter.dll : the network to audio card adapter (to be used on a slave machine started with the NetJack driver). - netadapter.dll : the network to audio card adapter (to be used on a slave machine started with an audio driver). - jack_connect.exe, jack_disconnect.exe, jack_lsp.exe, jack_metro.exe, jack_load.exe, jack_unload.exe, jack_netsource.exe tools. - JackRouter.dll : an ASIO/JACK driver that allows ASIO compatible applications to become JACK clients and access the JACK server. ASIO "jackified" applications appear with their names. Ableton Live, Samplitude, Reason, Arturia applications have been successfully tested. To install it, use "regsvr32 JackRouter.dll" in a terminal (use regsvr32 /u JackRouter.dll to uninstall). [VISTA special note: regsvr32 has to be used with "administrator" rights to properly register JackRouter.dll (Start Menu -> All Programs -> Accessories -> Right Click on Command Prompt -> Run As Administrator)]. A JackRouter.ini file is used by the driver to read parameters : an [IO] section allows to setup the number of input/output jack ports for the application and a [AUTO_CONNECT] section allows to setup jack ports auto connection mode to machine input/output. WARNING !! WARNING !! Depending of the used interface and driver settings, the PortAudio layer may add additional buffering between the real card interrupt and the jack server callback. This usually result in *unregular* calls of the jack server callback (for example if jack server used a 256 frames buffer and the card used a 512 frames, the jack server callback will be called twice every card interrupt). For proper functioning of jack server and clients in this case, the jack server has to be started in "synchronous" mode, using the "-S" parameter. ---------------------------- Known problems, limitations ---------------------------- - Thread handling in still not completely working : jack clients may "hang" when quitting. ---------------------------- Automatic server launch ---------------------------- Starting from the 0.64 version, automatic server launch from client is implemented : when the server is not yet running, QjackCtl if the client uses the "jack_client_open" API, the server will be started automatically. The server configuration is saved in a ".jackdrc" file located in the user home folder. The QjackCtl tool allows to save its configuration in this .jackdrc (setting can be done in QjackCtl Setup/Misc). If no configuration file is found, a default setup will be used. WARNING : automatic server launch is not implemented on Windows ------------------ Validations tools ------------------ jackdmp can possibly validate client applications by checking they are using the API in a correct manner (calling functions in the right order, correctly deallocating resources....) and produce a log file. A JACK_CLIENT_DEBUG environment variable must be used to activate client validation : use "export JACK_CLIENT_DEBUG=on". -------------- Documentation -------------- - a technical report presenting the new design and implementation. - doxygen generated documentation of the C++ code. --------- Versions --------- 0.1 : First published version 0.2 : Implements jack_time_frame, new -S (sync) mode : when "synch" mode is activated, the jackdmp server waits for the graph to be finished in the current cycle before writing the output buffers. Note : To experiment with the -S option, jackdmp must be launched in a console. 0.3 : Implement client zombification + correct feedback loop management + code cleanup. 0.31 : Correct bug in mixing code that caused Ardour + jackdmp to crash... 0.4 : Linux version, code cleanup, new -L parameter to activate the loopback driver (see Documentation), a number of loopback ports can be defined. Client validation tool. 0.41 : Add the ALSA MMAP_COMPLEX support for ALSA driver. Patch from Dmitry Daikov : compilation option to choose between "get_cycles" and "gettimeofday" to measure timing. 0.42 : Patch from Nick Mainsbridge. Correct default mode for ALSA driver. Correct XCode project. 0.43 : Correct freewheel mode. Optimize ALSA and coreaudio drivers. Correct OSX installation script. 0.44 : Patch from Dmitry Daikov : use clock_gettime by default for timing. Correct dirty buffer issue in CoreAudio driver. Updated doc. 0.45 : Script to remove the OSX binary stuff. Correct an export symbol issue that was preventing QjackCtl to work on OSX. Fix the consequences of the asynchronous semantic of connections/disconnections. 0.46 : Fix a bug in loop management. Fix a bug in driver loading/unloading code. Internal code cleanup for better 64 bits architecture support. Compilation on OSX/Intel. Add the -d option for coreaudio driver (display CoreAudio devices internal name). 0.47 : More fix for 64 bits compilation. Correct ALSA driver. Create a specific folder for jackdmp drivers. Use /dev/shm as default for fifo and sockets. "Install" and "Remove" script for smoother use with regular jack. 0.48 : Finish software monitoring implementation for ALSA and CoreAudio drivers. Simpler shared library management on OSX. 0.49 : Internal connection manager code cleanup. 0.50 : Transport API implementation. 0.51 : Correct bugs in transport API implementation. 0.52 : Universal version for Mac Intel and PPC. Improvement of CoreAudio driver for half duplex cases. 0.53 : Correct JackPilotMP tool on OSX. Correct CoreAudio driver for half duplex cases. Fix a bug in transport for "unactivated" clients. Fix a bug when removing "unactivated" clients from the server. Tested on Linux/PPC. 0.54 : Use the latest shm implementation that solve the uncleaned shm segment problem on OSX. Close still opened file descriptors (report from Giso Grimm). Updated html documentation. 0.55 : Windows version. Correct management of monitor ports in ALSA driver. Engine code cleanup. Apply Rui patch for more consistent parameter naming in coreaudio driver. Correct JackProcessSync::TimedWait : time-out was not computed correctly. Check the return code of NotifyAddClient in JackEngine. 0.56 : Correct SetBufferSize in coreaudio driver, portaudio driver and JackServer. Real-time notifications for Windows version. In the PortAudio backend, display more informations for installed WinMME, DirectSound and ASIO drivers. 0.57 : Correct bug in Mutex code in JackClientPipeThread::HandleRequest. ASIO JackRouter driver supports more applications. Updated HTML documentation. Windows dll binaries are compiled in "release" mode. 0.58 : Correct a bug introduced in 0.55 version that was preventing coreaudio audio inputs to work. Restructured code structure after import on svn. 0.59 : Various fixes in Windows version. Signal handling in the Windows server. Improved JackRouter ASIO/Jack bridge on Windows. Rename global "verbose" in "jack_verbose" to avoid symbol clash with PureData. Add a new cpu testing/loading client. Correct server SetBufferSize in case of failure. Correct PortAudio driver help. Use -D to setup ADDON_DIR on OSX and Linux. Synchronize ALSA backend with jack one. 0.60 : Improve audio driver synchronous code to better handle possible time-out cases. Correct JackWinEnvent::Allocate (handle the ERROR_ALREADY_EXISTS case). Correct JackEngine::ClientExternalNew. 0.61 : Tom Szilagyi memory leak fix in ringbuffer.c. Move client refnum management in JackEngine. Shared_ports renamed to shared_graph. Add call to the init callback (set up using the jack_set_thread_init_callback API) in Real-Time and Notification threads. Define a new 'kActivateClient' notification. New server/client data transfer model to fix a 64 bits system bug. Fix a device name reversal bug in ALSA driver. Implement thread.h API. 0.62 : More client debug code : check if the client is still valid in every JackDebugClient method, check if the library context is still valid in every API call. Uses a time out value of 10 sec in freewheel mode (like jack). More robust activation/deactivation code, especially in case of client crash. New LockAllMemory and UnlockAllMemory functions. Use pthread_attr_setstacksize in JackPosixThread class. Add Pieter Palmers FreeBob driver. Thibault LeMeur ALSA driver patch. Thom Johansen fix for port buffer alignment issues. Better error checking in PortAudio driver. 0.63 : Correct back JackAlsaDriver::Read method. Dmitry Baikov patch for JackGraphManager.cpp. Merge JackGraphManager Remove and Release method in a unique Release method. Dmitry Baikov jackmp-time patch : add jack_get_time, jack_time_to_frames, jack_frames_to_time. Add missing -D__SMP__in OSX project. Add new jack_port_set_alias, jack_port_unset_alias and jack_port_get_aliases API. Steven Chamberlain patch to fix jack_port_by_id export. Steven Chamberlain patch to fix jack_port_type. Test for jack_port_type behaviour in jack_test.cpp tool. Add jack_set_client_registration_callback API. Add "callback exiting" and "jack_frame_time" tests in jack_test. 0.64 : Checking in the server to avoid calling the clients if no callback are registered. Correct deprecated jack_set_sample_rate_callback to return 0 instead of -1. Dmitry Baikov buffer size patch. Correct notification for kActivateClient event. Correct JackEngine::ClientCloseAux (when called from JackEngine::ClientExternalOpen). Correct JackWinEvent::Allocate. Automatic client renaming. Add "systemic" latencies management in CoreAudio driver. Automatic server launch. Removes unneeded 'volatile' for JackTransportEngine::fWriteCounter. 0.65 : Fix backend port alias management (renaming in system:xxx). Fix a bug in JackLibClient::Open introduced when adding automatic client renaming. Fix a bug in jack_test. Correct JackShmMem destructor. Correct end case in JackClient::Execute. Correct JackMachSemaphore::Disconnect. Implement server temporary (-T) mode. Make "Rename" a method of JackPort class, call it from driver Attach method. Server/library protocol checking implementation. 0.66 : Internal cleanup. Windows JackRouter.dll version 0.16 : use of "jack_client_open" API to allow automatic client renaming, better Windows VISTA support, new JackRouter.ini file. 0.67 : Correct jack_client_open "status" management. Rename server_name from "default" to "jackdmp_default" to avoid conflict with regular jackd server. Fix a resource leak issue in JackCoreAudioDriver::Close(). Better implement "jack_client_open" when linking a client with the server library. Correct "jack_register_server" in shm.c. Add missing timestamps.c and timestamps.h files. Correctly export public headers in OSX frameworks. Suppress JackEngine::ClientInternalCloseIm method. Use .jackdrc file (instead of .jackdmprc). Install script now creates a link "jackd ==> jackdmp" so that automatic launch can work correctly. Paul Davis patch for -r (--replace-registry) feature. Internal loadable client implementation. Fix JackEngine::Close() method. Windows JackRouter.dll version 0.17: 32 integer sample format. 0.68 : Internal loadable client implementation, winpipe version added. Reorganize jack headers. Improve Linux install/remove scripts. Use LIB_DIR variable for 64 bits related compilation (drivers location). More generic Linux script. Correct jack_acquire_real_time_scheduling on OSX. Merge of Dmitry Baikov MIDI branch. Correct JackGraphManager::GetPortsAux to use port type. Remove JackEngineTiming class: code moved in JackEngineControl. Add midiseq and midisine examples. Cleanup old zombification code. Linux Makefile now install jack headers. Use of JACK_CLIENT_DEBUG environment variable to activate debug client mode. Definition of JACK_LOCATION variable using -D in the Makefile. Restore jack 0.103.0 MIDI API version. Fix a bug in freewheel management in async mode: drivers now receive the kStartFreewheelCallback and kStopFreewheelCallback notifications. Server and user directory related code moved in a JackTools file. Client name rewriting to remove path characters (used in fifo naming). Correct ALSA driver Attach method: internal driver may have changed the buffer_size and sample_rate values. Add JackWinSemaphore class. Add an implementation for obsolete jack_internal_client_new and jack_internal_client_close. Add missing jack_port_type_size. Use of JackWinSemaphore instead of JackWinEvent for inter-process synchronization. Correct types.h for use with MINGW on Windows. Move OSX start/stop notification mechanism in Jackdmp.cpp. Correct CheckPort in JackAPI.cpp. 0.69 : On OSX, use CFNotificationCenterPostNotificationWithOptions with kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions for server ==> JackRouter plugin notification. On OSX, use jack server name in notification system. Correct fPeriodUsecs computation in JackAudioDriver::SetBufferSize and JackAudioDriver::SetSampleRate. Correct JackMachNotifyChannel::ClientNotify. Correct bug in CoreAudio driver sample rate management. Add a sample_rate change listener in CoreAudio driver. Correct sample_rate management in JackCoreAudioDriver::Open. Better handling in sample_rate change listener. Pieter Palmers FFADO driver and scons based build. Pieter Palmers second new build system: scons and Makefile based build. Tim Blechmann scons patch. Change string management for proper compilation with gcc 4.2.2. JackLog cleanup. Cleanup in CoreAudio driver. Tim Blechmann patch for JackGraphManager::GetPortsAux memory leak, Tim Blechmann patch for scons install. Dmitry Baikov MIDI patch : alsa_seqmidi and alsa_rammidi drivers. CoreAudio driver improvement : detect and notify abnormal situations (stopped driver in case of SR change...). 0.70 : Updated API to match jack 0.109.0 version. Update in usx2y.c and JackPort.cpp to match jackd 0.109.2. Latest jack_lsp code from jack SVN. Add jack_mp_thread_wait client example. Add jack_thread_wait client example. Remove checking thread in CoreAudio driver, better device state change recovery strategy: the driver is stopped and restarted. Move transport related methods from JackEngine to JackServer. Tim Blechmann sse optimization patch for JackaudioPort::MixAudioBuffer, use of Apple Accelerate framework on OSX. Remove use of assert in JackFifo, JackMachSemaphore, and JackPosixSemaphore: print an error instead. Correct "server_connect": close the communication channel. More robust external API. Use SetAlias for port naming. Use jackd midi port naming scheme. Notify ports unregistration in JackEngine::ClientCloseAux. Fix in JackClient::Error(): when RT thread is failing and calling Shutdown, Shutdown was not desactivating the client correctly. 0.71 : Add port register/unregister notification in JackAlsaDriver. Correct JACK_port_unregister in MIDI backend. Add TimeCallback in JackDebugClient class. Correct jack_get_time propotype. Correct JackSocketClientChannel::ClientClose to use ServerSyncCall instead of ServerAsyncCall. Better documentation in jack.h. libjackdmp.so renamed to libjackservermp.so and same for OSX framework. Define an internal jack_client_open_aux needed for library wrapper feature. Remove unneeded jack_port_connect API. Correct jack_port_get_connections function (should return NULL when no connections). In thread model, execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished). Fix engine real-time notification (was broken since ??). Implements wrapper layer. Correct jack_port_get_total_latency. Correct all backend playback port latency in case of "asynchronous" mode (1 buffer more). Add test for jack_cycle_wait, jack_cycle_wait and jack_set_process_thread API. RT scheduling for OSX thread (when used in dummy driver). Add -L (extra output latency in aynchronous mode) in CoreAudio driver. New JackLockedEngine decorator class to serialize access from ALSA Midi thread, command thread and in-server clients. Use engine in JackAlsaDriver::port_register and JackAlsaDriver::port_unregister. Fix connect notification to deliver *one* notification only. Correct JackClient::Activate so that first kGraphOrderCallback can be received by the client notification thread. New jack_server_control client to test notifications when linked to the server library. Synchronise transport.h with latest jackd version (Video handling). Transport timebase fix. Dmitry Baikov patch for alsa_rawmidi driver. Pieter Palmers patch for FFADO driver. Add an Init method for blocking drivers to be decorated using JackThreadedDriver class. Correct PortRegister, port name checking must be done on server side. Correct a missing parameter in the usage message of jack_midiseq. New SetNonBlocking method for JackSocket. Correct a dirty port array issue in JackGraphManager::GetPortsAux. 1.9.0 : Waf based build system : Nedko Arnaudov, Grame for preliminary OSX support. Control API, dbus based server control access : Nedko Arnaudov, Grame. NetJack2 components (in progress) : jack_net backend, netmanager, audioadapter, netadapter : Romain Moret, Grame. Code restructuring to help port on other architectures : Michael Voigt. Code cleanup/optimization : Tim Blechmann. Improve handling of server internal clients that can now be loaded/unloaded using the new server control API : Grame. A lot of bug fix and improvements. 1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from JACK1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest JACK1 memops functions. Synchronize JACK2 public headers with JACK1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter. 1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). 1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend. 1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver. 1.9.5 : Dynamic choice of maximum port number. More robust sample rate change handling code in JackCoreAudioDriver. Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). Fix port_rename callback : now both old name and new name are given as parameters. Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). Check dynamic port-max value. Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). Josh Green ALSA driver capture only patch. When threads are cancelled, the exception has to be rethrown. Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. Mario Lang alsa_io time calculation overflow patch. Shared memory manager was calling abort in case of fatal error, now return an error in caller. Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. 1.9.6 : Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them.Correct JackGraphManager::DeactivatePort. Correct JackMachServerChannel::Execute : keep running even in error cases. Raise JACK_PROTOCOL_VERSION number. Arnold Krille firewire patch. Raise JACK_DRIVER_PARAM_STRING_MAX and JACK_PARAM_STRING_MAX to 127 otherwise some audio drivers cannot be loaded on OSX. Fix some file header to have library side code use LGPL. On Windows, now use TRE library for regexp (BSD license instead of GPL license). ffado-portname-sync.patch from ticket #163 applied. Remove call to exit in library code. Make jack_connect/jack_disconnect wait for effective port connection/disconnection. Add tests to validate intclient.h API. On Linux, inter-process synchronization primitive switched to POSIX semaphore. In JackCoreAudioDriver, move code called in MeasureCallback to be called once in IO thread. David Garcia Garzon netone patch. Fix from Fernando Lopez-Lezcano for compilation on fc13. Fix JackPosixSemaphore::TimedWait : same behavior as JackPosixSemaphore::Wait regarding EINTR. David Garcia Garzon unused_pkt_buf_field_jack2 netone patch. Arnold Krille firewire snooping patch. Jan Engelhardt patch for get_cycles on SPARC. Adrian Knoth hurd.patch, kfreebsd-fix.patch and alpha_ia64-sigsegv.patch from ticket 177. Adrian Knoth fix for linux cycle.h (ticket 188). In JackCoreAudioDriver, fix an issue when no value is given for input. 1.9.7 : Sync JackAlsaDriver::alsa_driver_check_card_type with JACK1 backend. Correct JackServer::Open to avoid a race when control API is used on OSX. Improve backend error handling: fatal error returned by Read/Write now cause a Process failure (so a thread exit for blocking backends). Recoverable ones (XRuns..) are now treated internally in ALSA, FreeBob and FFADO backends. In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start. Correct symbols export in backends on OSX. ALSA backend : suspend/resume handling. Correct dummy driver. Adrian Knoth jack_lsp patch. Remove JackPortIsActive flag. New latency API implementation. ComputeTotalLatencies now a client/server call. Add latent test client for latency API. Also print playback and capture latency in jack_lsp. jack_client_has_session_callback implementation. Check requested buffer size and limit to 1..8192 - avoids weird behaviour caused by jack_bufsize foobar. jack_port_type_get_buffer_size implementation. Stop using alloca and allocate buffer on the heap for alsa_io. Rename jdelay to jack_iodelay as per Fons' request. Call buffer size callback in activate (actually this is done on client side in the RT thread Init method). Add jack_midi_dump client. Synchronize net JACK1 with JACK1 version. Synchronize jack_connect/jack_disconnect with JACK1 version. Correct JackNetMaster::SetBufferSize. Use jack_default_audio_sample_t instead of float consistently, fix ticket #201. -X now allows to add several slave backends, add -I to load several internal clients. Rework internal slave driver management, JackServerGlobals now handle same parameters as jackdmp. Correct JackEngine::NotifyGraphReorder, update JackDebugClient with latest API. Devin Anderson server-ctl-proposal branch merged on trunk: improved control API, slave backend reworked. Implement renaming in JackDriver::Open to avoid name collision (thanks Devin Anderson). Correct alsa_driver_restart (thanks Devin Anderson). Correction of jack_connect/jack_disconnect: use of jack_activate and volatile keyword for thread shared variable. Correction of JackNetOneDriver for latest CELT API. Synchronize JackWeakAPI.cpp with new APIs. 1.9.8 : Merge newer-midi branch (Devin Anderson redesign of the MIDI drivers: alsarawmidi, ffado, coremidi and winmme). Correction in jackdmp.cpp: notify_server_stop should be done after server destruction. Correct driver lifetime management. Add XRun detection in PortAudio driver. CELT code for NetJack2. Merge branch switch-master-port-registration-notifications: correct driver port registration. Libjacknet in progress. Correct MIDI in NetJack2. Correct OSX real-time thread setup. Correct rd_acquire in dbus code. Correct NetJack2 connection handling. SaveConnections/RestoreConnections in NetDriver and JackAudioDriver. Special version of jack_attach_shm/jack_release_shm on client side for POSIX shared memory, to solve a memory leak issue. Another round of code improvements to handle completely buggy Digidesign CoreAudio user-land driver. Special CATCH_CLOSE_EXCEPTION_RETURN to handle Close API calls. Add JACK_NETJACK_PORT and JACK_NETJACK_MULTICAST environment variables for NetJack2. NetJack2 now only send data on network only is ports are connected both sides. Fix for "starting two instances of same app in parallel does not work" bug. Enable explicit channel mapping in CoreAudio driver. New JackTimedDriver class to be used by JackDummyDriver, JackNetDriver and JackNetOneDriver classes. More robust code in synchronization primitives and in JackMessageBuffer. More robust Control API implementation. Add jackctl_driver_get_type in Control API. Singleton behaviour for JackCoreMidiDriver and JackWinMMEDriver. John Emmas patch for DSP CPU computation. John Emmas Windows server launching patch. Fix jack_set_port_name API. Enable local access in NetJack2 code. Dynamic port management in JACK/CoreMidi bridge. 1.9.9 : Adrian Knoth fix in midiseq.c. Fix library symbols export issue. Cleanup drivers and internals loading code. jackctl_driver_params_parse API moved in public control.h. More general drivers/internals loading model on Windows. Factorize code the server/client request in JackRequestDecoder class. More robust server/client protocol. Implement shutdown for in server clients. Better time-out management in NetJack2. Experimental system port alias use in Windows JackRouter. Improve ShutDown in NetManager. Correct ShutDown in JackInternalClient and JackLibClient. Fix NetJack2 initialisation bug. Add EndTime function (especially for Windows). Rename JackProcessSync in JackPosixProcessSync. A bit more robust JackMessageBuffer implementation (in progress). Check server API callback from notification thread. Use a time-out in notification channel write function. Fix lock management in JackEngine. In control API, UNIX like sigset_t replaced by more abstract jackctl_sigmask_t * opaque struct. Improve libjacknet master mode. Remove JACK_32_64 flag, so POST_PACKED_STRUCTURE now always used. POST_PACKED_STRUCTURE used for jack_latency_range_t type. Rework JackMessageBuffer. [firewire] Introduce UpdateLatencies() in FFADO backend. [firewire] Allow FFADO backend to change the buffer size. Update waf. New jack_get_cycle_times() implementation from Fons Adriennsen. Align buffers to 32 byte boundaries to allow AVX processing. Extend jack_control to have parameter reset commands. Fix alsa driver parameter order. Control API: Enforce driver/internal parameter order. Fix in ALSA adapter. Devin Anderson patch for Jack/CoreMIDI duplicated messages. Change framework installation hierarchy for OSX Mountain Lion. Update JackCoreAudioDriver and JackCoreAudioAdapter with more recent API. jack_control: fix epr command. Add opus support to NetJack2. More robust channel mapping handling in JackCoreAudioDriver. netjack1/netone opus support. controlapi: fix double free on master switch. Use string ids in the alsa device list. netjack/opus: don't re-init en/decoders. Correct JackPortAudioDriver::Open : special case for ASIO drivers. 1.9.10 : More robust code in JackPortAudioDriver to handle buffer size change and backend switching. Fix bus error on ARM platforms. Dynamically scan and print backend and internal names in jackd. CoreMIDI driver fixes. Rework NetJack2 code (OPUS codec on OSX, latency management, libjacknet code). Correct auto-connect for audioadapter. Add IIO driver. Merge of Nedko no-self-connect branch. Fix freewheel mode. JackServer::SwitchMaster now correctly notify buffer_size and sample_rate changes, cleanup/improvements in JackNetDriver. Tim Mayberry : Add support for building with mingw compiler. Merge of Kim Jeong Yeon Android branch. Partial port of metadata API. 1.9.11 : Various corrections in NetJack2 code. Partial buffers can now be transmitted with libjacknet API. Including S24_LE/BE formats to linux ALSA driver. More robust shared memory allocator. Allow autostart of jackd on OSX where device-names can contain spaces. Correct CoreAudio devices aggregation code. Waf and wscripts improvement and update. More flexible RT priority setup on Windows. New JackProxyDriver. Various fixes in JACK MIDI code. Fix return value of SetTimebaseCallback(). Correct netmanager latency reporting. Implement new jack_port_rename and JackPortRenameCallback API. For OSX El Capitan support, use of Posix semaphore and move of Frameworks in /Library folder. Fix CPU hogging of the midi_thread(). Release audio devices when alsa_driver_new fails. String management fix. Correct JackDriver::Open : call to fGraphManager->SetBufferSize has to use current fEngineControl->fBufferSize value. Use ARM neon intrinsics for AudioBufferMixdown. Fix Netjack alignment. Various wscript improvements and cleanup. Fix initialization of several class variables. Heap-allocate client matrix in topo sort. Add a toggle command to transport utility, to allow toggling between play and stop state. Avoid side effects from parsing of "version" option in jackd. Allow firewire device be selected via -d. Add ARM-NEON acceleration for all non-dithering sample conversion functions. Add jack_simdtest utility. Use Linux futex as JackSynchro. Add autoclose option to jack_load. 1.9.12 : Fix Windows build issues. Fix build with gcc-7. Show hint when DBus device reservation fails. Add support for internal session files. This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, QjackCtl, Jack-Rack, SooperLooper, AlsaPlayer... ------------------------------------ General known problems, limitations ------------------------------------ - zombification of clients is not implemented - memory locking is implemented for shared data only The package is available at http://www.grame.fr/~letz/jackdmp.html ============================================= Grame : Computer Music Research Laboratory Web : http://www.grame.fr/Research E-mail : letz@grame.fr ============================================= 1.9.12~dfsg/man/0000755000000000000000000000000013214314510012113 5ustar rootroot1.9.12~dfsg/man/jack_showtime.00000644000000000000000000000047613214314510015032 0ustar rootroot.TH JACK_SHOWTIME "1" "!DATE!" "!VERSION!" .SH NAME jack_showtime \- The JACK Audio Connection Kit example client .SH SYNOPSIS .B jack_showtime .SH DESCRIPTION .B jack_showtime prints the current timebase information to stdout .SH AUTHOR Paul Davis .PP This manpage was written by Stefan Schwandter 1.9.12~dfsg/man/jack_load.00000644000000000000000000000162213214314510014104 0ustar rootroot.TH JACK_LOAD "1" "!DATE!" "!VERSION!" .SH NAME jack_load \- JACK toolkit client for loading in-process clients .SH SYNOPSIS \fBjack_load\fR [ \fI-i\fR initstring ] [ \fI-s\fR servername ] [\fI-w\fR ] client-name so-name [ initstring ] .SH DESCRIPTION \fBjack_load\fR is a JACK toolkit client. It loads the specified plugin and creates an in-process client. .SH ARGUMENTS .PP The client-name must be a currently unused client name. .PP The so-name is the name of file that client code is stored in (typically, \fIclientname.so\fR) .SH OPTIONS .TP \fB-i\fR, \fB--init\fR init-string .br initialization string passed to the in-process client. Note that this can also be specified as the last argument on the command line. .TP \fB-s\fR, \fB--server\fR servername .br Name of JACK server to connect to .TP \fB-w\fR, \fB--wait\fR Wait for a signal (eg. from Ctrl-c) and then unload the client. .SH AUTHOR Jeremy Hall 1.9.12~dfsg/man/jack_freewheel.00000644000000000000000000000120013214314510015123 0ustar rootroot.TH JACK_FREEWHEEL "1" "!DATE!" "!VERSION!" .SH NAME jack_freewheel \- JACK toolkit client to control freewheeling mode .SH SYNOPSIS .B jack_freewheel [y|n] .SH DESCRIPTION .B jack_freewheel Turns freewheeling mode on (y) or off (n). While in freewheeling mode, the JACK server does not wait in between process() calls, and does not read or write data from/to any audio interface. That results in the JACK graph processing data as fast as possible. Freewheeling makes fast exports to files possible. .PP There is no useful reason to use this tool other than testing. JACK clients that use freewheeling will turn it on and off themselves. 1.9.12~dfsg/man/jack_bufsize.00000644000000000000000000000066313214314510014640 0ustar rootroot.TH JACK_BUFSIZE "1" "!DATE!" "!VERSION!" .SH NAME jack_bufsize \- JACK toolkit client to change the JACK buffer size .SH SYNOPSIS .B jack_bufsize bufsize .SH DESCRIPTION .B jack_bufsize jack_bufsize sets the size of the buffer (frames per period) used in JACK. This change happens on-line (the JACK server and its clients do not need to be restarted). .br When invoked without arguments, it prints the current bufsize, and exits. 1.9.12~dfsg/man/alsa_out.00000644000000000000000000000002313214314510013776 0ustar rootroot.so man1/alsa_in.1 1.9.12~dfsg/man/jack_unload.00000644000000000000000000000073413214314510014452 0ustar rootroot.TH JACK_UNLOAD "1" "!DATE!" "!VERSION!" .SH NAME jack_unload \- The JACK Audio Connection Kit example client .SH SYNOPSIS .B jack_unload client-name .PP The client-name must be the name of a loaded client that can be unloaded. .SH DESCRIPTION .B jack_unload is the counterpart to .B jack_load and unloads the specified client. .SH EXAMPLE .B jack_unload in_process_test .SH AUTHOR Jeremy Hall .PP This manpage was written by Robert Jordens for Debian. 1.9.12~dfsg/man/jack_simple_client.00000644000000000000000000000105713214314510016016 0ustar rootroot.TH JACK_CONNECT "1" "!DATE!" "!VERSION!" .SH NAME jack_simple_client \- The JACK Audio Connection Kit example client .SH SYNOPSYS .B jack_simple_client client-name .PP The client-name must be a yet unused client name. .SH DESCRIPTION .B jack_simple_client is an example client for the JACK Audio Connection Kit. It creates two ports (client-name:input and client-name:output) that pass the data unmodified. .SH EXAMPLE jack_simple_client in_process_test .SH AUTHOR Jeremy Hall .PP This manpage was written by Robert Jordens for Debian. 1.9.12~dfsg/man/jack_connect.00000644000000000000000000000105213214314510014613 0ustar rootroot.TH JACK_CONNECT "1" "!DATE!" "!VERSION!" .SH NAME \fBjack_connect\fR, \fBjack_disconnect\fR \- JACK toolkit clients for connecting & disconnecting ports .SH SYNOPSIS \fB jack_connect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2 \fB jack_disconnect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2 .SH DESCRIPTION \fBjack_connect\fR connects the two named ports. \fBjack_disconnect\fR disconnects the two named ports. .SH RETURNS The exit status is zero if successful, 1 otherwise 1.9.12~dfsg/man/jack_wait.00000644000000000000000000000200013214314510014120 0ustar rootroot.TH JACK_WAIT "1" "!DATE!" "!VERSION!" .SH NAME jack_wait \- JACK toolkit client to check and wait for existence/exit of jackd. .SH SYNOPSIS \fBjack_wait\fR [ \fI-s\fR | \fI--server\fR servername ] [ \fI-t\fR | \fI--timeout\fR timeout_seconds [ \fI-cqwhv\fR ] .SH DESCRIPTION \fBjack_wait\fR When invoked with \fI-c\fR it only checks for the existence of a jack server. When invoked with \fI-w\fR the program will wait for a jackd to be available. The \fI-q\fR makes it wait for the jackd to exit. .SH OPTIONS .TP \fB-w\fR, \fB--wait\fR .br Wait for jackd to be available. .TP \fB-q\fR, \fB--quit\fR .br Wait for jackd quit. .TP \fB-c\fR, \fB--check\fR .br Only check for existence of jackd, and exit. .TP \fB-s\fR, \fB--server\fR \fIservername\fR .br Connect to the jack server named \fIservername\fR .TP \fB-t\fR, \fB--timeout\fR \fItimeout_seconds\fR .br Only wait \fItimeout_seconds\fR. .TP \fB-h\fR, \fB--help\fR .br Display help/usage message .TP \fB-v\fR, \fB--version\fR .br Output version information and exit 1.9.12~dfsg/man/jack_netsource.00000644000000000000000000000450713214314510015201 0ustar rootroot.TH JACK_NETSOURCE "1" "!DATE!" "!VERSION!" .SH NAME jack_netsource \- Netjack Master client for one slave .SH SYNOPSIS \fBjack_netsource\fR [ \fI-H\fR hostname ] [ \fIoptions\fR ] .SH DESCRIPTION \fBjack_netsource\fR The Master side of a netjack connection. Represents the slave jackd -dnet in the master jack graph. Most connection parameters are configured via the netsource, and the slave will set itself up according to the commandline option given to jack_netsource. .br Netjack allows low latency audio connections over general IP networks. When using celt for compression, it is even possible to establish transatlantic links, with latencies not much over the actual ping time. .br But the main usecase is of course a LAN, where it can achieve one jack period of latency. .SH OPTIONS .TP \fB-h\fR this help text .TP \fB-H\fR \fIslave host\fR .br Host name of the slave JACK .TP \fB-o\fR \fInum channels\fR .br Number of audio playback channels .TP \fB-i\fR \fInum channels\fR .br Number of audio capture channels .TP \fB-O\fR \fInum channels\fR .br Number of midi playback channels .TP \fB-I\fR \fInum channels\fR .br Number of midi capture channels .TP \fB-n\fR \fIperiods\fR .br Network latency in JACK periods .TP \fB-p\fR \fIport\fR .br UDP port that the slave is listening on .TP \fB-r\fR \fIreply port\fR .br UDP port that we are listening on .TP \fB-B\fR \fIbind port\fR .br reply port, for use in NAT environments .TP \fB-b\fR \fIbitdepth\fR .br Set transport to use 16bit or 8bit .TP \fB-c\fR \fIbytes\fR .br Use CELT encoding with per period and channel .TP \fB-m\fR \fImtu\fR .br Assume this mtu for the link .TP \fB-R\fR \fIN\fR .br Redundancy: send out packets N times. .TP \fB-e\fR .br skip host-to-network endianness conversion .TP \fB-N\fR \fIjack name\fR .br Reports a different client name to jack .TP .TP \fB-s\fR, \fB--server\fR \fIservername\fR .br Connect to the jack server named \fIservername\fR .TP \fB-h\fR, \fB--help\fR .br Display help/usage message .TP \fB-v\fR, \fB--version\fR .br Output version information and exit .SH EXAMPLES .PP run a 4 audio channel bidirectional link with one period of latency and no midi channels. Audio data is flowing uncompressed over the wire: .br On \fIhostA\fR: .IP \fBjackd \-d alsa \fR .br \fBjack_netsource \-H hostB -n1 -i4 -o4 -I0 -O0 \fR .PP On \fIhostB\fR: .IP \fBjackd \-d net \fR 1.9.12~dfsg/man/jack_impulse_grabber.00000644000000000000000000000052713214314510016332 0ustar rootroot.TH JACK_IMPULSE_GRABBER "1" "!DATE!" "!VERSION!" .SH NAME jack_impulse_grabber \- JACK toolkit client to grab an impulse (response) .SH SYNOPSIS \fBjack_impulse_grabber\fR \fB-d\fR \fIduration\fR [\fI-f\fR (C|gnuplot)] .SH DESCRIPTION \fBjack_impulse_grabber\fR is a JACK example client for collecting impulses recordings from JACK ports. 1.9.12~dfsg/man/jack_metro.00000644000000000000000000000210513214314510014310 0ustar rootroot.TH JACK_METRO "1" "!DATE!" "!VERSION!" .SH NAME jack_metro \- JACK toolkit metronome .SH SYNOPSIS \fBjack_metro\fR [ \fI-n\fR name ] [ \fI-f\fR hz ] [ \fI-D\fR msecs ] [\fI-a\fR % ] [ \fI-d\fR % ] \fI-b\fR bpm .SH DESCRIPTION \fBjack_metro\fR is a simple metronome for JACK. It generates a synthetic "tick" sound for every beat. Note that is does \fBnot\fR connect its output port by default - to hear the sound it makes you must connect them using some other tool. .SH OPTIONS .TP \fB-n\fR, \fB--name\fR .br Specify a name for this instance of the metronome. .TP \fB-f\fR, \fB--frequency\fR Hz .br Define the frequency of the "tick" in Hz. .TP \fB-D\fR, \fB--duration\fR msecs .br Define the duration of the "tick" in milliseconds. .TP \fB-a\fR, \fB--attack\fR %-age .br Define the duration of the attack phase of the "tick" as a percentage of the duration. .TP \fB-d\fR, \fB--decay\fR %-age .br Define the duration of the decay phase of the "tick" as a percentage of the duration. .TP \fB--b\fR, \fB--bpm\fR bpm .br Define the number of beats per minute. .SH AUTHOR Anthony Van Groningen 1.9.12~dfsg/man/jackrec.00000644000000000000000000000201713214314510013576 0ustar rootroot.TH JACKREC "1" "!DATE!" "!VERSION!" .SH NAME jackrec \- JACK toolkit client for recording audio .SH SYNOPSIS .B jackrec \-f filename \-d seconds [ \-b bitdepth ] port1 [ port2 ... ] .SH DESCRIPTION .B jackrec is a basic, but useful, audio recorder that will record audio from 1 or more JACK ports to a file on disk. The file format is always RIFF/WAV, with samples stored as signed integers. The sample bit depth can be selected using the \fI-b\fR option. The file will have as many channels as there are ports specified on the command line - each channel will contain the data recorded from one port. The user should generally specify the duration (in seconds) using the \fI-d\fR option. If not specified, jackrec will record until terminated by a signal (eg. from Ctrl-c). .PP This application is not intended to be a heavy duty audio recorder, and originated as an example client to show how to handle threading and disk I/O in a JACK client. However, it is a useful, simple recorder and is included in the JACK toolkit as a result. 1.9.12~dfsg/man/wscript0000644000000000000000000000034313214314510013531 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 import re import os def build(bld): bld.exec_command('cd man ; sh fill_template %s' % bld.env['JACK_VERSION']) bld.install_files(bld.env['MANDIR'], bld.path.ant_glob('*.1')) 1.9.12~dfsg/man/fill_template0000644000000000000000000000026713214314510014664 0ustar rootroot#!/bin/sh d="" [ -z "$SOURCE_DATE_EPOCH" ] || d=--date=@$SOURCE_DATE_EPOCH for i in *.0 ; do sed -e "s/!VERSION!/${1}/g" -e "s/!DATE!/`date $d '+%B %Y'`/g" < ${i} > ${i%%0}1 done 1.9.12~dfsg/man/jack_lsp.00000644000000000000000000000205313214314510013762 0ustar rootroot.TH JACK_LSP "1" "!DATE!" "!VERSION!" .SH NAME jack_lsp \- JACK toolkit client to list informtion on ports .SH SYNOPSIS \fBjack_lsp\fR [ \fI-s\fR | \fI--server\fR servername ] [ \fI-AclLptvh\fR ] .SH DESCRIPTION \fBjack_lsp\fR lists all known ports associated with a JACK server. It can also optionally list various kinds of information about each port. .SH OPTIONS .TP \fB-s\fR, \fB--server\fR \fIservername\fR .br Connect to the jack server named \fIservername\fR .TP \fB-A\fR, \fB--aliases\fR .br List aliases for each port .TP \fB-c\fR, \fB--connections\fR .br List connections to/from each port .TP \fB-l\fR, \fB--latency\fR .br Display per-port latency in frames at each port .TP \fB-L\fR, \fI--latency\fR .br Display total latency in frames at each port .TP \fB-p\fR, \fB--properties\fR .br Display port properties. Output may include input|output, can-monitor, physical, terminal .TP \fB-t\fR, \fB--type\fR .br Display port type .TP \fB-h\fR, \fB--help\fR .br Display help/usage message .TP \fB-v\fR, \fB--version\fR .br Output version information and exit 1.9.12~dfsg/man/jackd.00000644000000000000000000005306113214314510013255 0ustar rootroot.TH "JACKD" "1" "!DATE!" "!VERSION!" "" .SH "NAME" jackd \- JACK Audio Connection Kit sound server .SH "SYNOPSIS" \fBjackd\fR [\fIoptions\fR] \fB\-d\fI backend \fR [\fIbackend\-parameters\fR] .br \fBjackd \-\-help\fR .SH "DESCRIPTION" \fBjackd\fR is the JACK audio server daemon, a low\-latency audio server. Originally written for the GNU/Linux operating system, it also supports Mac OS X and various Unix platforms. JACK can connect a number of different client applications to an audio device and also to each other. Most clients are external, running in their own processes as normal applications. JACK also supports internal clients, which run within the \fBjackd\fR process using a loadable "plugin" interface. JACK differs from other audio servers in being designed from the ground up for professional audio work. It focuses on two key areas: synchronous execution of all clients, and low latency operation. For the latest JACK information, please consult the web site, <\fBhttp://www.jackaudio.org\fR>. .SH "OPTIONS" .TP \fB\-d, \-\-driver \fIbackend\fR [\fIbackend\-parameters\fR ] .br Select the audio interface backend. The current list of supported backends is: \fBalsa\fR, \fBcoreaudio\fR, \fBdummy\fR, \fBfreebob\fR, \fBoss\fR \fBsun\fR and \fBportaudio\fR. They are not all available on all platforms. All \fIbackend\-parameters\fR are optional. .TP \fB\-h, \-\-help\fR .br Print a brief usage message describing the main \fBjackd\fR options. These do not include \fIbackend\-parameters\fR, which are listed using the \fB\-\-help\fR option for each specific backend. Examples below show how to list them. .TP \fB\-m, \-\-no\-mlock\fR Do not attempt to lock memory, even if \fB\-\-realtime\fR. .TP \fB\-n, \-\-name\fR \fIserver\-name\fR Name this \fBjackd\fR instance \fIserver\-name\fR. If unspecified, this name comes from the \fB$JACK_DEFAULT_SERVER\fR environment variable. It will be "default" if that is not defined. .TP \fB\-p, \-\-port\-max \fI n\fR Set the maximum number of ports the JACK server can manage. The default value is 256. .TP \fB\-\-replace-registry\fR .br Remove the shared memory registry used by all JACK server instances before startup. This should rarely be used, and is intended only for occasions when the structure of this registry changes in ways that are incompatible across JACK versions (which is rare). .TP \fB\-R, \-\-realtime\fR .br Use realtime scheduling (default = true). This is needed for reliable low\-latency performance. On many systems, it requires \fBjackd\fR to run with special scheduler and memory allocation privileges, which may be obtained in several ways. .TP \fB\-r, \-\-no-realtime\fR .br Do not use realtime scheduling. .TP \fB\-P, \-\-realtime\-priority \fIint\fR When running \fB\-\-realtime\fR, set the scheduler priority to \fIint\fR. .TP \fB\-\-silent\fR Silence any output during operation. .TP \fB\-T, \-\-temporary\fR Exit once all clients have closed their connections. .TP \fB\-t, \-\-timeout \fIint\fR .br Set client timeout limit in milliseconds. The default is 500 msec. In realtime mode the client timeout must be smaller than the watchdog timeout (5000 msec). .TP \fB\-Z, \-\-nozombies\fR .br Prevent JACK from ever kicking out clients because they were too slow. This cancels the effect any specified timeout value, but JACK and its clients are still subject to the supervision of the watchdog thread or its equivalent. .TP \fB\-C, \-\-internal-session-file \fIinternal-session-file\fR .br Load internal clients and connections from \fIinternal-session-file\fR. Each line of this configuration file starts with a command. The following commands are available: .br \fBl(oad)\fR \fIclient-name lib-name client-args\fR .br With this command an internal JACK client will be instantiated. \fIclient-name\fR and \fIlib-name\fR cannot contain spaces. The rest of the line will be interpreted as \fIclient-args\fR and sent to the client library. .br \fBc(on)\fR \fIsource-port destination-port\fR .br With this command a source port will be connected to a destination port. \fIsource-port\fR and \fIdestination-port\fR cannot contain spaces. .br Comments are allowed, they start with \fB#\fR. .br An example configuration could look like the following: .br l inprocess1 inprocess l amp1 jalv http://lv2plug.in/plugins/eg-amp .br c amp:out system:playback_1 .TP \fB\-u, \-\-unlock\fR .br Unlock libraries GTK+, QT, FLTK, Wine. .TP \fB\-v, \-\-verbose\fR Give verbose output. .TP \fB\-c, \-\-clocksource\fR (\fI h(pet) \fR | \fI s(ystem) \fR) Select a specific wall clock (HPET timer, System timer). .TP \fB\-V, \-\-version\fR Print the current JACK version number and exit. .SS ALSA BACKEND OPTIONS .TP \fB\-C, \-\-capture\fR [ \fIname\fR ] Provide only capture ports, unless combined with \-D or \-P. Parameterally set capture device name. .TP \fB\-d, \-\-device \fIname\fR .br The ALSA pcm device \fIname\fR to use. If none is specified, JACK will use "hw:0", the first hardware card defined in \fB/etc/modules.conf\fR. .TP \fB\-z, \-\-dither [rectangular,triangular,shaped,none] Set dithering mode. If \fBnone\fR or unspecified, dithering is off. Only the first letter of the mode name is required. .TP \fB\-D, \-\-duplex\fR Provide both capture and playback ports. Defaults to on unless only one of \-P or \-C is specified. .TP \fB\-h, \-\-help\fR Print a brief usage message describing only the \fBalsa\fR backend parameters. .TP \fB\-M, \-\-hwmeter\fR .br Enable hardware metering for devices that support it. Otherwise, use software metering. .TP \fB\-H, \-\-hwmon\fR .br Enable hardware monitoring of capture ports. This is a method for obtaining "zero latency" monitoring of audio input. It requires support in hardware and from the underlying ALSA device driver. When enabled, requests to monitor capture ports will be satisfied by creating a direct signal path between audio interface input and output connectors, with no processing by the host computer at all. This offers the lowest possible latency for the monitored signal. Presently (March 2003), only the RME Hammerfall series and cards based on the ICE1712 chipset (M\-Audio Delta series, Terratec, and others) support \fB\-\-hwmon\fR. In the future, some consumer cards may also be supported by modifying their mixer settings. Without \fB\-\-hwmon\fR, port monitoring requires JACK to read audio into system memory, then copy it back out to the hardware again, imposing the basic JACK system latency determined by the \fB\-\-period\fR and \fB\-\-nperiods\fR parameters. .TP \fB\-i, \-\-inchannels \fIint\fR .br Number of capture channels. Default is maximum supported by hardware. .TP \fB\-I \-\-input\-latency\fR Extra input latency (frames) (default: 0) .TP \fB\-n, \-\-nperiods \fIint\fR .br Specify the number of periods of playback latency. In seconds, this corresponds to \fB\-\-nperiods\fR times \fB\-\-period\fR divided by \fB\-\-rate\fR. The default is 2, the minimum allowable. For most devices, there is no need for any other value with the \fB\-\-realtime\fR option. Without realtime privileges or with boards providing unreliable interrupts (like ymfpci), a larger value may yield fewer xruns. This can also help if the system is not tuned for reliable realtime scheduling. For most ALSA devices, the hardware buffer has exactly \fB\-\-period\fR times \fB\-\-nperiods\fR frames. Some devices demand a larger buffer. If so, JACK will use the smallest possible buffer containing at least \fB\-\-nperiods\fR, but the playback latency does not increase. For USB audio devices it is recommended to use \fB\-n 3\fR. Firewire devices supported by FFADO (formerly Freebob) are configured with \fB\-n 3\fR by default. .TP \fB\-o, \-\-outchannels \fIint\fR .br Number of playback channels. Default is maximum supported by hardware. .TP \fB\-O \-\-output\-latency\fR Extra output latency (frames) (default: 0) .TP \fB\-P, \-\-playback\fR [ \fIname\fR ] Provide only playback ports, unless combined with \-D or \-C. Optionally set playback device name. .TP \fB\-p, \-\-period \fIint\fR .br Specify the number of frames between JACK \fBprocess()\fR calls. This value must be a power of 2, and the default is 1024. If you need low latency, set \fB\-p\fR as low as you can go without seeing xruns. A larger period size yields higher latency, but makes xruns less likely. The JACK capture latency in seconds is \fB\-\-period\fR divided by \fB\-\-rate\fR. .TP \fB\-r, \-\-rate \fIint\fR Specify the sample rate. The default is 48000. .TP \fB\-S, \-\-shorts .br Try to configure card for 16\-bit samples first, only trying 32\-bits if unsuccessful. Default is to prefer 32\-bit samples. .TP \fB\-s, \-\-softmode\fR .br Ignore xruns reported by the ALSA driver. This makes JACK less likely to disconnect unresponsive ports when running without \fB\-\-realtime\fR. .TP \fB\-X, \-\-midi \fR[\fIseq\fR|\fIraw\fR] .br Specify which ALSA MIDI system to provide access to. Using \fBraw\fR will provide a set of JACK MIDI ports that correspond to each raw ALSA device on the machine. Using \fBseq\fR will provide a set of JACK MIDI ports that correspond to each ALSA "sequencer" client (which includes each hardware MIDI port on the machine). \fBraw\fR provides slightly better performance but does not permit JACK MIDI communication with software written to use the ALSA "sequencer" API. .SS COREAUDIO BACKEND PARAMETERS .TP \fB\-c \-\-channels\fR Maximum number of channels (default: 2) .TP \fB\-i \-\-inchannels\fR Maximum number of input channels (default: 2) .TP \fB\-o \-\-outchannels\fR Maximum number of output channels (default: 2) .TP \fB\-C \-\-capture\fR Whether or not to capture (default: true) .TP \fB\-P \-\-playback\fR Whether or not to playback (default: true) .TP \fB\-D \-\-monitor\fR Provide monitor ports for the output (default: false) .TP \fB\-D \-\-duplex\fR Capture and playback (default: true) .TP \fB\-r \-\-rate\fR Sample rate (default: 44100) .TP \fB\-p \-\-period\fR Frames per period (default: 128). Must be a power of 2. .TP \fB\-d \-\-device\fR CoreAudio device name (default: none) .TP \fB\-I \-\-input\-latency\fR Extra input latency (frames) (default: 0) .TP \fB\-O \-\-output\-latency\fR Extra output latency (frames) (default: 0) .TP \fB\-l \-\-list\-devices \fR Display available CoreAudio devices (default: false) .TP \fB\-H \-\-hog \fR Take exclusive access of the audio device (default: false) .TP \fB\-L \-\-async\-latency \fR Extra output latency in asynchronous mode (percent) (default: 100) .TP \fB\-G \-\-grain \fR Computation grain in RT thread (percent) (default: 100) .TP \fB\-s \-\-clock\-drift \fR Whether to compensate clock drift in dynamically created aggregate device (default: false) .SS DUMMY BACKEND PARAMETERS .TP \fB\-C, \-\-capture \fIint\fR Specify number of capture ports. The default value is 2. .TP \fB\-P, \-\-playback \fIint\fR Specify number of playback ports. The default value is 2. .TP \fB\-r, \-\-rate \fIint\fR Specify sample rate. The default value is 48000. .TP \fB\-p, \-\-period \fIint\fR Specify the number of frames between JACK \fBprocess()\fR calls. This value must be a power of 2, and the default is 1024. If you need low latency, set \fB\-p\fR as low as you can go without seeing xruns. A larger period size yields higher latency, but makes xruns less likely. The JACK capture latency in seconds is \fB\-\-period\fR divided by \fB\-\-rate\fR. .TP \fB\-w, \-\-wait \fIint\fR Specify number of usecs to wait between engine processes. The default value is 21333. .SS NETONE BACKEND PARAMETERS .TP \fB\-i, \-\-audio\-ins \fIint\fR Number of capture channels (default: 2) .TP \fB\-o, \-\-audio\-outs \fIint\fR Number of playback channels (default: 2) .TP \fB\-I, \-\-midi\-ins \fIint\fR Number of midi capture channels (default: 1) .TP \fB\-O, \-\-midi\-outs \fIint\fR Number of midi playback channels (default: 1) .TP \fB\-r, \-\-rate \fIint\fR Sample rate (default: 48000) .TP \fB\-p, \-\-period \fIint\fR Frames per period (default: 1024) .TP \fB\-n, \-\-num\-periods \fIint\fR Network latency setting in no. of periods (default: 5) .TP \fB\-l, \-\-listen\-port \fIint\fR The socket port we are listening on for sync packets (default: 3000) .TP \fB\-f, \-\-factor \fIint\fR Factor for sample rate reduction (default: 1) .TP \fB\-u, \-\-upstream\-factor \fIint\fR Factor for sample rate reduction on the upstream (default: 0) .TP \fB\-c, \-\-celt \fIint\fR sets celt encoding and number of kbits per channel (default: 0) .TP \fB\-b, \-\-bit\-depth \fIint\fR Sample bit\-depth (0 for float, 8 for 8bit and 16 for 16bit) (default: 0) .TP \fB\-t, \-\-transport\-sync \fIint\fR Whether to slave the transport to the master transport (default: true) .TP \fB\-a, \-\-autoconf \fIint\fR Whether to use Autoconfig, or just start. (default: true) .TP \fB\-R, \-\-redundancy \fIint\fR Send packets N times (default: 1) .TP \fB\-e, \-\-native\-endian \fIint\fR Dont convert samples to network byte order. (default: false) .TP \fB\-J, \-\-jitterval \fIint\fR attempted jitterbuffer microseconds on master (default: 0) .TP \fB\-D, \-\-always\-deadline \fIint\fR always use deadline (default: false) .SS OSS BACKEND PARAMETERS .TP \fB\-r, \-\-rate \fIint\fR Specify the sample rate. The default is 48000. .TP \fB\-p, \-\-period \fIint\fR Specify the number of frames between JACK \fBprocess()\fR calls. This value must be a power of 2, and the default is 1024. If you need low latency, set \fB\-p\fR as low as you can go without seeing xruns. A larger period size yields higher latency, but makes xruns less likely. The JACK capture latency in seconds is \fB\-\-period\fR divided by \fB\-\-rate\fR. .TP \fB\-n, \-\-nperiods \fIint\fR Specify the number of periods in the hardware buffer. The default is 2. The period size (\fB\-p\fR) times \fB\-\-nperiods\fR times four is the JACK buffer size in bytes. The JACK output latency in seconds is \fB\-\-nperiods\fR times \fB\-\-period\fR divided by \fB\-\-rate\fR. .TP \fB\-w, \-\-wordlength \fIint\fR Specify the sample size in bits. The default is 16. .TP \fB\-i, \-\-inchannels \fIint\fR Specify how many channels to capture (default: 2) .TP \fB\-o, \-\-outchannels \fIint\fR Specify number of playback channels (default: 2) .TP \fB\-C, \-\-capture \fIdevice_file\fR Specify input device for capture (default: /dev/dsp) .TP \fB\-P, \-\-playback \fIdevice_file\fR Specify output device for playback (default: /dev/dsp) .TP \fB\-b, \-\-ignorehwbuf \fIboolean\fR Specify, whether to ignore hardware period size (default: false) .TP \fB\-I \-\-input\-latency\fR Extra input latency (frames) (default: 0) .TP \fB\-O \-\-output\-latency\fR Extra output latency (frames) (default: 0) .SS SUN BACKEND PARAMETERS .TP \fB\-r, \-\-rate \fIint\fR Specify the sample rate. The default is 48000. .TP \fB\-p, \-\-period \fIint\fR Specify the number of frames between JACK \fBprocess()\fR calls. This value must be a power of 2, and the default is 1024. If you need low latency, set \fB\-p\fR as low as you can go without seeing xruns. A larger period size yields higher latency, but makes xruns less likely. The JACK capture latency in seconds is \fB\-\-period\fR divided by \fB\-\-rate\fR. .TP \fB\-n, \-\-nperiods \fIint\fR Specify the number of periods in the hardware buffer. The default is 2. The period size (\fB\-p\fR) times \fB\-\-nperiods\fR times four (assuming 2 channels 16-bit samples) is the JACK buffer size in bytes. The JACK output latency in seconds is \fB\-\-nperiods\fR times \fB\-\-period\fR divided by \fB\-\-rate\fR. .TP \fB\-w, \-\-wordlength \fIint\fR Specify the sample size in bits. The default is 16. .TP \fB\-i, \-\-inchannels \fIint\fR Specify how many channels to capture (default: 2) .TP \fB\-o, \-\-outchannels \fIint\fR Specify number of playback channels (default: 2) .TP \fB\-C, \-\-capture \fIdevice_file\fR Specify input device for capture (default: /dev/audio) .TP \fB\-P, \-\-playback \fIdevice_file\fR Specify output device for playback (default: /dev/audio) .TP \fB\-b, \-\-ignorehwbuf \fIboolean\fR Specify, whether to ignore hardware period size (default: false) .SS PORTAUDIO BACKEND PARAMETERS .TP \fB\-c \-\-channel\fR Maximum number of channels (default: all available hardware channels) .TP \fB\-i \-\-channelin\fR Maximum number of input channels (default: all available hardware channels) .TP \fB\-I \-\-input\-latency\fR Extra input latency (frames) (default: 0) .TP \fB\-o \-\-channelout\fR Maximum number of output channels (default: all available hardware channels) .TP \fB\-O \-\-output\-latency\fR Extra output latency (frames) (default: 0) .TP \fB\-C \-\-capture\fR Whether or not to capture (default: true) .TP \fB\-P \-\-playback\fR Whether or not to playback (default: true) .TP \fB\-D \-\-duplex\fR Capture and playback (default: true) .TP \fB\-r \-\-rate\fR Sample rate (default: 48000) .TP \fB\-p \-\-period\fR Frames per period (default: 1024). Must be a power of 2. .TP \fB\-n \-\-name\fR Driver name (default: none) .TP \fB\-z \-\-dither\fR Dithering mode (default: none) .SH "EXAMPLES" .PP Print usage message for the parameters specific to each backend. .IP \fBjackd \-d alsa \-\-help\fR .br \fBjackd \-d coreaudio \-\-help\fR .br \fBjackd \-d net \-\-help\fR .br \fBjackd \-d dummy \-\-help\fR .br \fBjackd \-d firewire \-\-help\fR .br \fBjackd \-d freebob \-\-help\fR .br \fBjackd \-d oss \-\-help\fR .br \fBjackd \-d sun \-\-help\fR .br \fBjackd \-d portaudio \-\-help\fR .PP Run the JACK daemon with realtime priority using the first ALSA hardware card defined in \fB/etc/modules.conf\fR. .IP \fBjackstart \-\-realtime \-\-driver=alsa\fR .PP Run the JACK daemon with low latency giving verbose output, which can be helpful for trouble\-shooting system latency problems. A reasonably well\-tuned system with a good sound card and a low\-latency kernel can handle these values reliably. Some can do better. If you get xrun messages, try a larger buffer. Tuning a system for low latency can be challenging. The JACK FAQ, .I http://jackit.sourceforge.net/docs/faq.php\fR has some useful suggestions. .IP \fBjackstart \-Rv \-d alsa \-p 128 \-n 2 \-r 44100\fR .PP Run \fBjackd\fR with realtime priority using the "sblive" ALSA device defined in ~/.asoundrc. Apply shaped dithering to playback audio. .IP \fBjackd \-R \-d alsa \-d sblive \-\-dither=shaped\fR .PP Run \fBjackd\fR with no special privileges using the second ALSA hardware card defined in \fB/etc/modules.conf\fR. Any xruns reported by the ALSA backend will be ignored. The larger buffer helps reduce data loss. Rectangular dithering will be used for playback. .IP \fBjackd \-d alsa \-d hw:1 \-p2048 \-n3 \-\-softmode \-zr\fR .PP Run \fBjackd\fR in full\-duplex mode using the ALSA hw:0,0 device for playback and the hw:0,2 device for capture. .IP \fBjackd \-d alsa \-P hw:0,0 \-C hw:0,2\fR .PP Run \fBjackd\fR in playback\-only mode using the ALSA hw:0,0 device. .IP \fBjackd \-d alsa \-P hw:0,0\fR .SH "ENVIRONMENT" .br JACK is evolving a mechanism for automatically starting the server when needed. Any client started without a running JACK server will attempt to start one itself using the command line found in the first line of \fB$HOME/.jackdrc\fR if it exists, or \fB/etc/jackdrc\fR if it does not. If neither file exists, a built\-in default command will be used, including the \fB\-T\fR flag, which causes the server to shut down when all clients have exited. As a transition, this only happens when \fB$JACK_START_SERVER\fR is defined in the environment of the calling process. In the future this will become normal behavior. In either case, defining \fB$JACK_NO_START_SERVER\fR disables this feature. To change where JACK looks for the backend drivers, set \fB$JACK_DRIVER_DIR\fR. \fB$JACK_DEFAULT_SERVER\fR specifies the default server name. If not defined, the string "default" is used. If set in their respective environments, this affects \fBjackd\fR unless its \fB\-\-name\fR parameter is set, and all JACK clients unless they pass an explicit name to \fBjack_client_open()\fR. Defining \fB$JACK_NO_AUDIO_RESERVATION\fR will bypass audio device reservation via session bus (DBus). This can be useful if JACK was compiled with DBus support but should run on a headless system. \fB$JACK_PROMISCUOUS_SERVER\fR enables an alternate way of handling the various shared resources (Unix sockets, semaphores, ...). In this mode, the generated names will not contain the user id anymore, and the permissions of those resources will be relaxed, allowing clients from different users to talk with the same server. Moreover, on platforms that support it (all POSIX variants), if set to a valid Unix group name or id, the permissions will be restricted to that group, so only members of that group will be able to launch clients that talk to this server. Important note: it must be set with the same value for both server and clients to work as expected. .SH "SEE ALSO:" .PP .I http://www.jackaudio.org .br The official JACK website with news, docs and a list of JACK clients. .PP .I http://jackaudio.org/email .br The JACK developers' mailing list. Subscribe, to take part in development of JACK or JACK clients. User questions are also welcome, there is no user-specific mailing list. .PP .I http://www.jackosx.com/ .br Tools specific to the Mac OS X version of JACK. .PP .I http://www.alsa\-project.org .br The Advanced Linux Sound Architecture. .SH "BUGS" Please report bugs to .br .I http://trac.jackaudio.org/ .SH "AUTHORS" Architect and original implementor: Paul Davis .PP Original design Group: Paul Davis, David Olofson, Kai Vehmanen, Benno Sennoner, Richard Guenther, and other members of the Linux Audio Developers group. .PP Programming: Paul Davis, Jack O'Quin, Taybin Rutkin, Stephane Letz, Fernando Pablo Lopez-Lezcano, Steve Harris, Jeremy Hall, Andy Wingo, Kai Vehmanen, Melanie Thielker, Jussi Laako, Tilman Linneweh, Johnny Petrantoni, Torben Hohn. .PP Manpage written by Stefan Schwandter, Jack O'Quin and Alexandre Prokoudine. 1.9.12~dfsg/man/jack_samplerate.00000644000000000000000000000035013214314510015317 0ustar rootroot.TH JACK_SAMPLERATE "1" "!DATE!" "!VERSION!" .SH NAME jack_samplerate \- JACK toolkit client to print current samplerate .SH SYNOPSIS .B jack_samplerate .SH DESCRIPTION .B jack_samplerate prints the current samplerate, and exits. 1.9.12~dfsg/man/jack_transport.00000644000000000000000000000061613214314510015223 0ustar rootroot.TH JACK_TRANSPORT "1" "!DATE!" "!VERSION!" .SH NAME jack_transport \- JACK toolkit client for transport control .SH SYNOPSIS .B jack_transport .SH DESCRIPTION .B jack_transport is a toolkit client for the JACK Audio Connection Kit. It provides command-line control over the JACK transport system. Type help at jack_transport's command prompt to see the available commands. .SH AUTHOR Jeremy Hall 1.9.12~dfsg/man/alsa_in.00000644000000000000000000000674513214314510013616 0ustar rootroot.TH ALSA_IO "1" "!DATE!" "!VERSION!" .SH NAME \fBalsa_in\fR, \fBalsa_out\fR \- Jack clients that perform I/O with an alternate audio interface .SH SYNOPSIS \fBalsa_in\fR [\fIoptions\fR] .br \fBalsa_out\fR [\fIoptions\fR] .SH DESCRIPTION A JACK client that opens a specified audio interface (different to the one used by the JACK server, if any) and moves audio data between its JACK ports and the interface. alsa_in will provide data from the interface (potentially for capture); alsa_out will deliver data to it (for playback). The audio interface used by alsa_in/alsa_out does not need to be synchronized with JACK backend (or the hardware it might be using). alsa_in/alsa_out tries to resample the output stream in an attempt to compensate for drift between the two clocks. As of jack-0.116.3 this works almost perfectly. It takes some time, to reach absolute resample-rate stability. So give it some minutes (its intended to be running permanently anyways) .SH OPTIONS .TP \fB\-j \fI jack_client_name\fR .br Set Client Name. .TP \fB\-d \fI alsa_device\fR .br Use this Soundcard. .TP \fB\-v\fR .br Verbose, prints out resample coefficient and other parameters useful for debugging, every 500ms. also reports soft xruns. .TP \fB\-i\fR .br Instrumentation. This logs the 4 important parameters of the samplerate control algorithm every 1ms. You can pipe this into a file, and plot it. Should only be necessary, if it does not work as expected, and we need to adjust some of the obscure parameters, to make it work. Find me on irc.freenode.org #jack in order to set this up correctly. .TP \fB\-c \fI channels\fR .br Set Number of channels. .TP \fB\-r \fI sample_rate\fR .br Set sample_rate. The program resamples as necessary. So you can connect a 44k1 jackd to a soundcard only supporting 48k. (default is jack sample_rate) .TP \fB\-p \fI period_size\fR .br Set the period size. It is not related to the jackd period_size. Sometimes it affects the quality of the delay measurements. Setting this lower than the jackd period_size will only work, if you use a higher number of periods. .TP \fB\-n \fI num_period\fR .br Set number of periods. See note for period_size. .TP \fB\-q \fI quality\fR .br Set the quality of the resampler from 0 to 4. can significanly reduce cpu usage. .TP \fB\-m \fI max_diff\fR .br The value when a soft xrun occurs. Basically the window, in which the dma pointer may jitter. I don't think its necessary to play with this anymore. .TP \fB\-t \fI target_delay\fR .br The delay alsa_io should try to approach. Same as for max_diff. It will be setup based on \-p and \-n which is generally sufficient. .TP \fB\-s \fI smooth_array_size\fR .br This parameter controls the size of the array used for smoothing the delay measurement. Its default is 256. If you use a pretty low period size, you can lower the CPU usage a bit by decreasing this parameter. However most CPU time is spent in the resampling so this will not be much. .TP \fB\-C \fI P Control Clamp\fR .br If you have a PCI card, then the default value (15) of this parameter is too high for \-p64 \-n2... Setting it to 5 should fix that. Be aware that setting this parameter too low, lets the hf noise on the delay measurement come through onto the resamplerate, so this might degrade the quality of the output. (but its a threshold value, and it has been chosen, to mask the noise of a USB card, which has an amplitude which is 50 times higher than that of a PCI card, so 5 wont loose you any quality on a PCI card) .SH AUTHOR Torben Hohn 1.9.12~dfsg/man/jack_monitor_client.00000644000000000000000000000077713214314510016224 0ustar rootroot.TH JACK_CONNECT "1" "!DATE!" "!VERSION!" .SH NAME jack_monitor_client \- The JACK Audio Connection Kit example client .SH SYNOPSIS .B jack_monitor_client client-name .PP The client-name must be the name of a existing client that monitoring is to be enabled for. .SH DESCRIPTION .B jack_monitor_client is an example client for the JACK Audio Connection Kit. It enables monitoring for the specified client. .SH AUTHOR Jeremy Hall .PP This manpage was written by Robert Jordens for Debian. 1.9.12~dfsg/man/jack_disconnect.00000644000000000000000000000003013214314510015306 0ustar rootroot.so man1/jack_connect.1 1.9.12~dfsg/man/jack_iodelay.00000644000000000000000000000560313214314510014616 0ustar rootroot.TH JACK_IODELAY "1" "!DATE!" "!VERSION!" .SH NAME jack_iodelay \- JACK toolkit client to measure roundtrip latency .SH SYNOPSIS .B jack_iodelay .SH DESCRIPTION .B jack_iodelay will create one input and one output port, and then measures the latency (signal delay) between them. For this to work, the output port must be connected to its input port. The measurement is accurate to a resolution of greater than 1 sample. .PP The expected use is to connect jack_iodelay's output port to a hardware playback port, then use a physical loopback cable from the corresponding hardware output connector to an input connector, and to connect that corresponding hardware capture port to jack_iodelay's input port. This creates a roundtrip that goes through any analog-to-digital and digital-to-analog converters that are present in the audio hardware. .PP Although the hardware loopback latency is the expected use, it is also possible to use jack_iodelay to measure the latency along any fully connected signal path, such as those involving other JACK clients. .PP Once jack_iodelay completes its measurement it will print the total latency it has detected. This will include the JACK buffer length in addition to any other latency in the signal path. It will continue to print the value every 0.5 seconds so that if you wish you can vary aspects of the signal path to see their effect on the measured latency. .PP If no incoming signal is detected from the input port, jack_iodelay will print .PP \fT Signal below threshold... .\fR .PP every second until this changes (e.g. until you establish the correct connections). .PP To use the value measured by jack_iodelay with the -I and -O arguments of a JACK backend (also called Input Latency and Output Latency in the setup dialog of qjackctl), you must subtract the JACK buffer size from the result. The buffer size is determined by multiplying the number of frames per period (given to the jackd backend by the -p or --period option) by the number of periods per buffer (given to the jackd backend by the -n or --nperiods option). Note that JACK2 will add an implicit additional period when using the default asynchronous mode, so for JACK1 or JACK2 in synchronous mode, the buffer size is n*p, but for JACK2 in asynchronous mode the buffer size is (n+1)*p. Once the JACK buffer size is subtracted from the measured latency, the result is the "extra" latency due to the interface hardware. Then, if you believe that the latency is equally distributed between the input and output parts of your audio hardware (extremely likely), divide the result by two and use that for input and output latency values. Doing this measurement will enable JACK clients that use the JACK latency API to accurately position/delay audio to keep signals synchronized even when there are inherent delays in the end-to-end signal pathways. .SH AUTHOR Originally written in C++ by Fons Adriaensen, ported to C by Torben Hohn. 1.9.12~dfsg/tests/0000755000000000000000000000000013214314510012502 5ustar rootroot1.9.12~dfsg/tests/iodelay.cpp0000644000000000000000000001616613214314510014646 0ustar rootroot/* Copyright (C) 2003-2008 Fons Adriaensen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ // -------------------------------------------------------------------------------- #include #include #define __STDC_LIMIT_MACROS #include #include #include #include struct Freq { int p; int f; float xa; float ya; float x1; float y1; float x2; float y2; }; struct MTDM { double _del; double _err; float _wlp; int _cnt; int _inv; struct Freq _freq [13]; }; struct MTDM * mtdm_new (double fsamp) { int i; struct Freq *F; struct MTDM *retval = (MTDM *)malloc( sizeof(struct MTDM) ); if (retval==NULL) return NULL; retval->_cnt = 0; retval->_inv = 0; retval->_freq [0].f = 4096; retval->_freq [1].f = 2048; retval->_freq [2].f = 3072; retval->_freq [3].f = 2560; retval->_freq [4].f = 2304; retval->_freq [5].f = 2176; retval->_freq [6].f = 1088; retval->_freq [7].f = 1312; retval->_freq [8].f = 1552; retval->_freq [9].f = 1800; retval->_freq [10].f = 3332; retval->_freq [11].f = 3586; retval->_freq [12].f = 3841; retval->_wlp = 200.0f / fsamp; for (i = 0, F = retval->_freq; i < 13; i++, F++) { F->p = 128; F->xa = F->ya = 0.0f; F->x1 = F->y1 = 0.0f; F->x2 = F->y2 = 0.0f; } return retval; } int mtdm_process (struct MTDM *self, size_t len, float *ip, float *op) { int i; float vip, vop, a, c, s; struct Freq *F; while (len--) { vop = 0.0f; vip = *ip++; for (i = 0, F = self->_freq; i < 13; i++, F++) { a = 2 * (float) M_PI * (F->p & 65535) / 65536.0; F->p += F->f; c = cosf (a); s = -sinf (a); vop += (i ? 0.01f : 0.20f) * s; F->xa += s * vip; F->ya += c * vip; } *op++ = vop; if (++self->_cnt == 16) { for (i = 0, F = self->_freq; i < 13; i++, F++) { F->x1 += self->_wlp * (F->xa - F->x1 + 1e-20); F->y1 += self->_wlp * (F->ya - F->y1 + 1e-20); F->x2 += self->_wlp * (F->x1 - F->x2 + 1e-20); F->y2 += self->_wlp * (F->y1 - F->y2 + 1e-20); F->xa = F->ya = 0.0f; } self->_cnt = 0; } } return 0; } int mtdm_resolve (struct MTDM *self) { int i, k, m; double d, e, f0, p; struct Freq *F = self->_freq; if (hypot (F->x2, F->y2) < 0.001) return -1; d = atan2 (F->y2, F->x2) / (2 * M_PI); if (self->_inv) d += 0.5; if (d > 0.5) d -= 1.0; f0 = self->_freq [0].f; m = 1; self->_err = 0.0; for (i = 0; i < 12; i++) { F++; p = atan2 (F->y2, F->x2) / (2 * M_PI) - d * F->f / f0; if (self->_inv) p += 0.5; p -= floor (p); p *= 2; k = (int)(floor (p + 0.5)); e = fabs (p - k); if (e > self->_err) self->_err = e; if (e > 0.4) return 1; d += m * (k & 1); m *= 2; } self->_del = 16 * d; return 0; } void mtdm_invert (struct MTDM *self) { self->_inv ^= 1; } // -------------------------------------------------------------------------------- static struct MTDM *mtdm; static jack_client_t *jack_handle; static jack_port_t *jack_capt; static jack_port_t *jack_play; jack_latency_range_t capture_latency = {UINT32_MAX, UINT32_MAX}; jack_latency_range_t playback_latency = {UINT32_MAX, UINT32_MAX}; void latency_cb (jack_latency_callback_mode_t mode, void *arg) { jack_latency_range_t range; range.min = range.max = 0; if (mode == JackCaptureLatency) { jack_port_set_latency_range (jack_play, mode, &range); jack_port_get_latency_range (jack_capt, mode, &range); if ((range.min != capture_latency.min) || (range.max != capture_latency.max)) { capture_latency = range; printf ("new capture latency: [%d, %d]\n", range.min, range.max); } } else { jack_port_set_latency_range (jack_capt, mode, &range); jack_port_get_latency_range (jack_play, mode, &range); if ((range.min != playback_latency.min) || (range.max != playback_latency.max)) { playback_latency = range; printf ("new playback latency: [%d, %d]\n", range.min, range.max); } } } int jack_callback (jack_nframes_t nframes, void *arg) { float *ip, *op; ip = (float *)(jack_port_get_buffer (jack_capt, nframes)); op = (float *)(jack_port_get_buffer (jack_play, nframes)); mtdm_process (mtdm, nframes, ip, op); return 0; } int main (int ac, char *av []) { float t; jack_status_t s; jack_handle = jack_client_open ("jack_delay", JackNoStartServer, &s); if (jack_handle == 0) { fprintf (stderr, "Can't connect to Jack, is the server running ?\n"); exit (1); } mtdm = mtdm_new(jack_get_sample_rate(jack_handle)); jack_set_process_callback (jack_handle, jack_callback, 0); if (jack_set_latency_callback) jack_set_latency_callback (jack_handle, latency_cb, 0); jack_capt = jack_port_register (jack_handle, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); jack_play = jack_port_register (jack_handle, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); t = 1000.0f / jack_get_sample_rate (jack_handle); if (jack_activate (jack_handle)) { fprintf(stderr, "Can't activate Jack"); return 1; } while (1) { #ifdef WIN32 Sleep (250); #else usleep (250000); #endif if (mtdm_resolve (mtdm) < 0) printf ("Signal below threshold...\n"); else { jack_nframes_t systemic_latency; if (mtdm->_err > 0.3) { mtdm_invert ( mtdm ); mtdm_resolve ( mtdm ); } systemic_latency = (jack_nframes_t) floor (mtdm->_del - (capture_latency.max + playback_latency.max)); printf ("%10.3lf frames %10.3lf ms total roundtrip latency\n\textra loopback latency: %u frames\n\tuse %u for the backend arguments -I and -O", mtdm->_del, mtdm->_del * t, systemic_latency, systemic_latency/2); if (mtdm->_err > 0.2) printf (" ??"); if (mtdm->_inv) printf (" Inv"); printf ("\n"); } } return 0; } // -------------------------------------------------------------------------------- 1.9.12~dfsg/tests/cpu.c0000644000000000000000000001561213214314510013442 0ustar rootroot/* Copyright (C) 2005 Samuel TRACOL Copyright (C) 2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /** @file jack_cpu.c * * @brief This client test the capacity for jackd to kick out a to heavy cpu client. * */ #include #include #include #include #include #include #include jack_port_t *input_port; jack_port_t *output_port; jack_client_t *client; unsigned long sr; jack_nframes_t idle_time = 0; int percent_cpu = 0; int time_to_run = 0; int time_before_run = 0; int time_before_exit = 1; jack_nframes_t cur_buffer_size; /* a simple state machine for this client */ volatile enum { Init, Run, Exit } client_state = Init; void usage() { fprintf (stderr, "\n" "usage: jack_cpu \n" " [ --name OR -n client_name ]\n" " [ --time OR -t time_to_run (in seconds) ]\n" " [ --delay OR -d delay_before_cpuload__is_applied (in seconds) ]\n" " --cpu OR -c percent_cpu_load (1-99)\n" ); } int update_buffer_size(jack_nframes_t nframes, void *arg) { cur_buffer_size = nframes; printf("Buffer size = %d \n", cur_buffer_size); idle_time = (jack_nframes_t) (cur_buffer_size * percent_cpu / 100); printf("CPU load applies as %d sample delay.\n", idle_time); return 0; } /** * The process callback for this JACK application is called in a * special realtime thread once for each audio cycle. * */ int process(jack_nframes_t nframes, void *arg) { jack_default_audio_sample_t *in, *out; jack_nframes_t start_frame = jack_frame_time(client); in = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port, nframes); out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes); memset(out, 0, sizeof (jack_default_audio_sample_t) * nframes); while ((client_state == Run) && (jack_frame_time(client) < (start_frame + idle_time))) {} return 0; } /** * JACK calls this shutdown_callback if the server ever shuts down or * decides to disconnect the client. */ void jack_shutdown(void *arg) { fprintf(stderr, "JACK shut down, exiting ...\n"); exit (1); } int main(int argc, char *argv[]) { const char **ports; const char *client_name; int got_time = 0; jack_status_t status; int option_index; int opt; const char *options = "t:t:d:c:"; struct option long_options[] = { {"time", 1, 0, 't'}, {"name", 1, 0, 'n'}, {"delay", 1, 0, 'd'}, {"cpu", 1, 0, 'c'}, {0, 0, 0, 0} }; client_name = "jack-cpu"; while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { case 'n': client_name = optarg; break; case 't': time_to_run = atoi(optarg); break; case 'd': time_before_run = atoi(optarg); break; case 'c': percent_cpu = atoi(optarg); got_time = 1; break; default: fprintf(stderr, "unknown option %c\n", opt); usage(); } } if (!got_time) { fprintf(stderr, "CPU load not specified ! See usage as following :\n"); usage(); return -1; } if (time_to_run != 0) printf("Running jack-cpu for %d seconds...\n", time_to_run); /* open a client connection to the JACK server */ client = jack_client_open (client_name, JackNoStartServer, &status); if (client == NULL) { fprintf(stderr, "jack_client_open() failed : is jack server running ?\n"); exit(1); } cur_buffer_size = jack_get_buffer_size(client); printf("engine buffer size = %d \n", cur_buffer_size); printf("engine sample rate: %d Hz\n", jack_get_sample_rate(client)); idle_time = (jack_nframes_t) (cur_buffer_size * percent_cpu / 100); printf("CPU load applies as %d sample delay.\n", idle_time); /* tell the JACK server to call `process()' whenever there is work to be done. */ jack_set_process_callback(client, process, 0); /* tell the JACK server to call `jack_shutdown()' if it ever shuts down, either entirely, or if it just decides to stop calling us. */ jack_on_shutdown(client, jack_shutdown, 0); /* create two ports */ input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); printf("registering ports...\n"); if ((input_port == NULL) || (output_port == NULL)) { fprintf(stderr, "no more JACK ports available\n"); exit(1); } if (jack_set_buffer_size_callback(client, update_buffer_size, 0) != 0) { printf("Error when calling buffer_size_callback !"); return -1; } /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ printf("Activating as jackd client...\n"); if (jack_activate(client)) { fprintf(stderr, "cannot activate client"); exit(1); } /* Connect the ports. You can't do this before the client is * activated, because we can't make connections to clients * that aren't running. Note the confusing (but necessary) * orientation of the driver backend ports: playback ports are * "input" to the backend, and capture ports are "output" from * it. */ ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); if (ports == NULL) { fprintf(stderr, "no physical capture ports\n"); exit (1); } if (jack_connect(client, ports[0], jack_port_name(input_port))) { fprintf (stderr, "cannot connect input ports\n"); } jack_free(ports); ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput); if (ports == NULL) { fprintf(stderr, "no physical playback ports\n"); exit(1); } if (jack_connect(client, jack_port_name (output_port), ports[0])) { fprintf(stderr, "cannot connect output ports\n"); } jack_free(ports); if (time_before_run == 0) { client_state = Run; printf("Activating cpu load...\n"); } if (time_to_run !=0) time_before_exit = time_to_run + time_before_run; while (client_state != Exit) { if ((time_before_run > 0) && (client_state == Init)) time_before_run--; sleep(1); if ((time_before_run < 1) && (client_state != Run)) { client_state = Run; printf("Activating cpu load...\n"); } if (time_to_run != 0) time_before_exit--; if (time_before_exit < 1) client_state = Exit; } jack_client_close(client); printf("Exiting after a %d seconds run.\n", time_to_run); exit(0); } 1.9.12~dfsg/tests/testThread.cpp0000644000000000000000000000411613214314510015317 0ustar rootroot/* Copyright (C) 2004-2005 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include pthread_t fThread; char fName[256]; int fFifo; void* ThreadHandler(void* arg) { char c; printf("ThreadHandler\n"); try { while (1) { read(fFifo, &c, sizeof(c)); sleep(1); //pthread_testcancel(); } } catch (std::exception e) {} } int main(int argc, char * const argv[]) { int res; void* status; struct stat statbuf; printf("Thread test\n"); std::set_terminate(__gnu_cxx::__verbose_terminate_handler); sprintf(fName, "/tmp/fifo"); if (stat(fName, &statbuf)) { if (errno == ENOENT) { if (mkfifo(fName, 0666) < 0) { printf("Cannot create inter-client FIFO [%s]\n", fName); return 0; } } else { printf("Cannot check on FIFO %s\n", fName); return 0; } } else { if (!S_ISFIFO(statbuf.st_mode)) { printf("FIFO (%s) already exists, but is not a FIFO!\n", fName); return 0; } } if ((fFifo = open(fName, O_RDWR|O_CREAT, 0666)) < 0) { printf("Cannot open fifo [%s]", fName); return 0; } if (res = pthread_create(&fThread, 0, ThreadHandler, NULL)) { printf("Cannot set create thread %d\n", res); return 0; } sleep(3); printf("Cancel Thread\n"); pthread_cancel(fThread); pthread_join(fThread, &status); } 1.9.12~dfsg/tests/testMutex.cpp0000644000000000000000000001567713214314510015230 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #ifdef __APPLE__ #include "JackMachThread.h" #endif #include "JackPosixThread.h" #include "JackMutex.h" #include "thread.h" using namespace Jack; static void CleanupHandler(void * arg) { JackLockAble* locked = (JackLockAble*)arg; printf("CleanupHandler locked %px \n", locked); locked->Unlock(); } struct LockedObject : public JackLockAble { int fCount; LockedObject():fCount(0) {} virtual ~LockedObject() {} /* void LockedMethod1() { JackLock lock(this); fCount++; printf("LockedMethod1 self %x fCount %d\n", pthread_self(), fCount); if (fCount >= 1000) { printf("Terminate self %x\n", pthread_self()); pthread_exit(NULL); } } void LockedMethod2() { JackLock lock(this); fCount++; printf("LockedMethod2 self %x fCount %d\n", pthread_self(), fCount); if (fCount >= 1500) { printf("Terminate self %x\n", pthread_self()); pthread_exit(NULL); } } void LockedMethod3() { JackLock lock(this); fCount++; printf("LockedMethod3 self %x fCount %d\n", pthread_self(), fCount); if (fCount >= 3000) { printf("Terminate self %x\n", pthread_self()); pthread_exit(NULL); } } */ void LockedMethod1() { pthread_cleanup_push(CleanupHandler, this); Lock(); fCount++; //printf("LockedMethod1 self %x fCount %d\n", pthread_self(), fCount); if (fCount >= 1000) { printf("Terminate self = %px count = %d\n", pthread_self(), fCount); pthread_exit(NULL); } Unlock(); pthread_cleanup_pop(0); } void LockedMethod2() { pthread_cleanup_push(CleanupHandler, this); Lock(); fCount++; //printf("LockedMethod2 self %x fCount %d\n", pthread_self(), fCount); if (fCount >= 1500) { printf("Terminate self = %px count = %d\n", pthread_self(), fCount); pthread_exit(NULL); } Unlock(); pthread_cleanup_pop(0); } void LockedMethod3() { pthread_cleanup_push(CleanupHandler, this); Lock(); fCount++; //printf("LockedMethod3 self %x fCount %d\n", pthread_self(), fCount); if (fCount >= 3000) { printf("Terminate self = %px count = %d\n", pthread_self(), fCount); pthread_exit(NULL); } Unlock(); pthread_cleanup_pop(0); } }; struct TestThread : public JackRunnableInterface { JackMachThread* fThread; LockedObject* fObject; int fNum; TestThread(LockedObject* obj, int num) { printf("TestThread\n"); fThread = new JackMachThread(this); fObject = obj; fNum = num; fThread->StartSync(); } virtual ~TestThread() { printf("DELETE %px\n", fThread); fThread->Kill(); delete fThread; } bool Execute() { //printf("TestThread Execute\n"); switch (fNum) { case 1: fObject->LockedMethod1(); /* if (fObject->fCount >= 500) { printf("Terminate self %x\n", pthread_self()); fThread->Terminate(); } */ break; case 2: fObject->LockedMethod2(); /* if (fObject->fCount >= 1500) { printf("Terminate self %x\n", pthread_self()); fThread->Terminate(); } */ break; case 3: fObject->LockedMethod3(); /* if (fObject->fCount >= 2000) { printf("Terminate self %x\n", pthread_self()); fThread->Terminate(); } */ break; }; //usleep(fNum * 1000); return true; } }; static void* TestThread1_Execute(void* arg); struct TestThread1 : public JackRunnableInterface { pthread_t fThread; LockedObject* fObject; int fNum; TestThread1(LockedObject* obj, int num) { if (jack_client_create_thread(NULL, &fThread, 0, 0, TestThread1_Execute, this)) jack_error( "Can't create the network manager control thread." ); fObject = obj; fNum = num; } virtual ~TestThread1() {} bool Execute() { printf("TestThread Execute\n"); switch (fNum) { case 1: fObject->LockedMethod1(); break; case 2: fObject->LockedMethod2(); break; case 3: fObject->LockedMethod3(); break; }; //usleep(fNum * 1000); return true; } }; static void* TestThread1_Execute(void* arg) { TestThread1* obj = (TestThread1*)arg; while (true) { //printf("TestThread Execute\n"); switch (obj->fNum) { case 1: obj->fObject->LockedMethod1(); break; case 2: obj->fObject->LockedMethod2(); break; case 3: obj->fObject->LockedMethod3(); break; }; //usleep(obj->fNum * 1000); } return 0; } int main (int argc, char * const argv[]) { char c; LockedObject obj; TestThread th1(&obj, 1); TestThread th2(&obj, 2); TestThread th3(&obj, 3); /* LockedObject obj; TestThread1 th1(&obj, 1); TestThread th2(&obj, 2); TestThread th3(&obj, 3); */ /* while ((c = getchar()) != 'q') { } */ while (true) { usleep(1000); th1.fThread->Kill(); } /* th1.fThread->Kill(); th2.fThread->Kill(); th3.fThread->Kill(); while (true) { //usleep(100000); th1.fThread->Kill(); } */ } 1.9.12~dfsg/tests/external_metro.h0000644000000000000000000000342713214314510015711 0ustar rootroot/* Copyright (C) 2001 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: external_metro.h,v 1.3.2.1 2006/06/20 14:44:00 letz Exp $ */ #ifndef __external_metro__ #define __external_metro__ #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #include typedef jack_default_audio_sample_t sample_t; /*! \brief A class to test external clients */ struct ExternalMetro { jack_client_t *client; jack_port_t *input_port; jack_port_t *output_port; unsigned long sr; int freq; int bpm; jack_nframes_t tone_length, wave_length; sample_t *wave; double *amp; long offset ; ExternalMetro(int freq, double max_amp, int dur_arg, int bpm, const char* client_name = "metro"); virtual ~ExternalMetro(); static int process_audio (jack_nframes_t nframes, void* arg); static void shutdown (void* arg); }; #ifdef __cplusplus } #endif #endif 1.9.12~dfsg/tests/testAtomic.cpp0000644000000000000000000001142713214314510015327 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "JackAtomicState.h" #include "JackPosixThread.h" using namespace Jack; #define SIZE 1024 struct TestState { long fTable[SIZE]; long fReadCounter; long fWriteCounter; TestState() { for (int i = 0; i < SIZE; i++) { fTable[i] = 0; } fReadCounter = 0; fWriteCounter = 0; } virtual ~TestState() {} void Write() { fWriteCounter++; for (int i = 0; i < SIZE; i++) { fTable[i] = fTable[i] + 10; } } bool Read() { int val = fTable[0]; fReadCounter++; for (int i = 0; i < SIZE; i++) { if (fTable[i] != val) { printf("Read error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val); return false; } } return true; } bool ReadCopy(long* result) { int val = fTable[0]; fReadCounter++; for (int i = 0; i < SIZE; i++) { result[i] = fTable[i]; if (fTable[i] != val) { //printf("ReadCopy error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val); return false; } } return true; } bool Check(long* result) { int val = result[0]; for (int i = 0; i < SIZE; i++) { if (result[i] != val) { printf("Check error fReadCounter %ld, i %ld, curVal %ld, oldVal %ld\n", fReadCounter, i, fTable[i], val); return false; } } return true; } int GetVal() { return fTable[10]; } }; /*! \brief The state wrapped with the 2 state atomic class. */ class TestStateUser : public JackAtomicState { public: TestStateUser(){} virtual ~TestStateUser(){} void TestWriteMethod() { TestState* state = WriteNextStateStart(); state->Write(); state->Write(); state->Write(); WriteNextStateStop(); } void TestReadMethod() { TestState* state; int fCount = 0; long result[SIZE]; UInt16 cur_index; UInt16 next_index; do { cur_index = GetCurrentIndex(); fCount++; state = ReadCurrentState(); bool res = state->ReadCopy(result); next_index = GetCurrentIndex(); if (!res) printf("TestReadMethod fCount %ld cur %ld next %ld\n", fCount, cur_index, next_index); }while (cur_index != next_index); state->Check(result); } void TestReadRTMethod1() { TestState* state = TrySwitchState(); bool res = state->Read(); } void TestReadRTMethod2() { TestState* state = ReadCurrentState(); state->Read(); } }; /*! \brief Base class for reader/writer threads. */ struct TestThread : public JackRunnableInterface { JackPosixThread* fThread; TestStateUser* fObject; TestThread(TestStateUser* state):fObject(state) { fThread = new JackPosixThread(this); int res = fThread->Start(); } virtual ~TestThread() { fThread->Kill(); delete fThread; } }; /*! \brief "Real-time" reader thread. */ struct RTReaderThread : public TestThread { RTReaderThread(TestStateUser* state):TestThread(state) {} bool Execute() { fObject->TestReadRTMethod1(); for (int i = 0; i < 5; i++) { fObject->TestReadRTMethod2(); } usleep(50); return true; } }; /*! \brief Non "Real-time" reader thread. */ struct ReaderThread : public TestThread { ReaderThread(TestStateUser* state):TestThread(state) {} bool Execute() { fObject->TestReadMethod(); usleep(56); return true; } }; /*! \brief Writer thread. */ struct WriterThread : public TestThread { WriterThread(TestStateUser* state):TestThread(state) {} bool Execute() { fObject->TestWriteMethod(); usleep(75); return true; } }; int main(int argc, char * const argv[]) { char c; printf("Test concurrent access to a TestState data structure protected with the 2 state JackAtomicState class\n"); TestStateUser fObject; WriterThread writer(&fObject); RTReaderThread readerRT1(&fObject); ReaderThread reader1(&fObject); /* ReaderThread reader2(&fObject); ReaderThread reader3(&fObject); ReaderThread reader4(&fObject); ReaderThread reader5(&fObject); ReaderThread reader6(&fObject); */ while ((c = getchar()) != 'q') {} return 1; } 1.9.12~dfsg/tests/test.cpp0000644000000000000000000025024513214314510014175 0ustar rootroot/* Copyright (C) 2005 Samuel TRACOL for GRAME This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /** @file jack_test.c * * @brief This client test the jack API. * */ #include #include #include #ifndef WIN32 #include #endif #include #include #include #include #include #include #include #include #if defined(WIN32) && !defined(M_PI) #define M_PI 3.151592653 #endif #ifdef WIN32 #define jack_sleep(val) Sleep((val)) #else #define jack_sleep(val) usleep((val) * 1000) #endif typedef struct { jack_nframes_t ft; // running counter frame time jack_nframes_t fcs; // from sycle start... jack_nframes_t lft; // last frame time... } FrameTimeCollector; FILE *file; FrameTimeCollector* framecollect; FrameTimeCollector perpetualcollect; FrameTimeCollector lastperpetualcollect; int frames_collected = 0; // ports jack_port_t *output_port1; jack_port_t *output_port1b; jack_port_t *input_port2; jack_port_t *output_port2; jack_port_t *input_port1; // clients jack_client_t *client1; jack_client_t *client2; const char *client_name1; const char *client_name2; unsigned long sr; // sample rate // for time -t option int time_to_run = 0; int time_before_exit = 1; // standard error count int t_error = 0; int reorder = 0; // graph reorder callback int RT = 0; // is real time or not... int FW = 0; // freewheel mode int init_clbk = 0; // init callback int port_rename_clbk = 0; // portrename callback int i, j, k = 0; int port_callback_reg = 0; jack_nframes_t cur_buffer_size, old_buffer_size, cur_pos; int activated = 0; int count1, count2 = 0; // for freewheel int xrun = 0; int have_xrun = 0; // msg to tell the process1 function to write a special thing in the frametime file. int process1_activated = -1; // to control processing... int process2_activated = -1; // to control processing... unsigned long int index1 = 0; unsigned long int index2 = 0; jack_default_audio_sample_t *signal1; // signal source d'emission jack_default_audio_sample_t *signal2; // tableau de reception jack_transport_state_t ts; jack_position_t pos; jack_position_t request_pos; int silent_error = 0; // jack silent mode int verbose_mode = 0; int transport_mode = 1; jack_nframes_t input_ext_latency = 0; // test latency for PHY devices jack_nframes_t output_ext_latency = 0; // test latency for PHY devices int sync_called = 0; int starting_state = 1; int linecount = 0; // line counter for log file of sampleframe counter --> for graph function. int linebuf = 0; // reminders for graph analysis int linetransport = 0; int linefw = 0; int lineports = 0; int linecl2 = 0; int client_register = 0; /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* Callbacks & basics functions *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* */ void usage() { fprintf (stderr, "\n\n" "usage: jack_test \n" " [ --time OR -t time_to_run (in seconds) ]\n" " [ --quiet OR -q (quiet mode : without jack server errors) ]\n" " [ --verbose OR -v (verbose mode : no details on tests done. Only main results & errors) ]\n" " [ --transport OR -k (Do not test transport functions.) ]\n" " --realtime OR -R (jack is in rt mode)\n\n\n" ); exit(1); } void Log(const char *fmt, ...) { if (verbose_mode) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } } void Collect(FrameTimeCollector* TheFrame) { TheFrame->lft = jack_last_frame_time(client1); TheFrame->ft = jack_frame_time(client1); TheFrame->fcs = jack_frames_since_cycle_start(client1); } void Jack_Thread_Init_Callback(void *arg) { #ifdef WIN32 Log("Init callback has been successfully called from thread = %x. (msg from callback)\n", GetCurrentThread()); #else Log("Init callback has been successfully called from thread = %x. (msg from callback)\n", pthread_self()); #endif init_clbk = 1; } void Jack_Freewheel_Callback(int starting, void *arg) { Log("Freewheel callback has been successfully called with value %i. (msg from callback)\n", starting); FW = starting; } void Jack_Client_Registration_Callback(const char* name, int val, void *arg) { Log("Client registration callback name = %s has been successfully called with value %i. (msg from callback)\n", name, val); if (val) client_register++; else client_register--; } void Jack_Port_Rename_Callback(jack_port_id_t port, const char* old_name, const char* new_name, void *arg) { Log("Rename callback has been successfully called with old_name '%s' and new_name '%s'. (msg from callback)\n", old_name, new_name); port_rename_clbk = 1; } int Jack_Update_Buffer_Size(jack_nframes_t nframes, void *arg) { cur_buffer_size = jack_get_buffer_size(client1); Log("Buffer size = %d (msg from callback)\n", cur_buffer_size); return 0; } int Jack_XRun_Callback(void *arg) { xrun++; have_xrun = 1; Log("Xrun has been detected ! (msg from callback)\n"); return 0; } int Jack_Graph_Order_Callback(void *arg) { reorder++; return 0; } int Jack_Sample_Rate_Callback(jack_nframes_t nframes, void *arg) { Log("Sample rate : %i.\n", nframes); return 0; } void Jack_Error_Callback(const char *msg) { if (silent_error == 0) { fprintf(stderr, "error : %s (msg from callback)\n", msg); } } void jack_shutdown(void *arg) { printf("Jack_test has been kicked out by jackd !\n"); exit(1); } void jack_info_shutdown(jack_status_t code, const char* reason, void *arg) { printf("JACK server failure : %s\n", reason); exit(1); } void Jack_Port_Register(jack_port_id_t port, int mode, void *arg) { port_callback_reg++; } void Jack_Port_Connect(jack_port_id_t a, jack_port_id_t b, int connect, void* arg) { Log("PortConnect src = %ld dst = %ld onoff = %ld (msg from callback)\n", a, b, connect); } int Jack_Sync_Callback(jack_transport_state_t state, jack_position_t *pos, void *arg) { int res = 0; switch (state) { case JackTransportStarting: sync_called++; if (starting_state == 0) { Log("sync callback : Releasing status : now ready...\n"); res = 1; } else { if (sync_called == 1) { Log("sync callback : Holding status...\n"); } res = 0; } break; case JackTransportStopped: Log("sync callback : JackTransportStopped...\n"); res = 0; break; default: res = 0; break; } return res; } /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* processing functions *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* * Proccess1 is for client1 * 4 modes, activated with process1_activated * * -1 : idle mode * 0 : write zeros to output 1 * 1 : write continuously signal1 (sinusoidal test signal) to output1 * 3 : mode for summation test. While record (done by process2) is not running, write signal1 to both out1 & out1b. * when record begin (index2 > 0), write signal1 in phase opposition to out1 & out2 * 5 : Frames Time checking mode : write the array containing the three values of frame_time, frames cycles start and * last frame time during 150 cycles. */ int process1(jack_nframes_t nframes, void *arg) { if (FW == 0) { Collect(&perpetualcollect); if (have_xrun) { fprintf(file, "%i %i\n", (perpetualcollect.ft - lastperpetualcollect.ft), (2*cur_buffer_size)); have_xrun = 0; } else { fprintf(file, "%i 0\n", (perpetualcollect.ft - lastperpetualcollect.ft)); } linecount++; lastperpetualcollect.ft = perpetualcollect.ft; } jack_default_audio_sample_t *out1; jack_default_audio_sample_t *out1b; activated++; // counter of callback activation if (process1_activated == 1) { out1 = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port1, nframes); for (jack_nframes_t p = 0; p < nframes; p++) { out1[p] = signal1[index1]; index1++; if (index1 == 48000) index1 = 0; } } if (process1_activated == 3) { out1 = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port1, nframes); out1b = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port1b, nframes); for (jack_nframes_t p = 0; p < nframes; p++) { out1[p] = signal1[index1]; if (index2 != 0) { out1b[p] = ( -1 * signal1[index1]); } else { out1b[p] = signal1[index1]; } index1++; if (index1 == 48000) index1 = 0; } } if (process1_activated == 0) { out1 = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port1, nframes); memset (out1, 0, sizeof (jack_default_audio_sample_t) * nframes); //�crit des z�ros en sortie... } if (process1_activated == 5) { Collect(&framecollect[frames_collected]); frames_collected++; if (frames_collected > 798) { process1_activated = -1; } } return 0; } /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* * Proccess2 is for client2 * 3 modes, activated with process1_activated * * -1 : idle mode * 0 : idle mode * 1 : record in2 into signal2.(for first transmit test) * 2 : record in2 into signal2 while send signal1 in out2. used dor Tie data test. * 3 : record in2 into sigal2 for summation data test. * In records modes, at the end of the record (signal2 is full), it stop the test, setting both activation states to -1. */ int process2(jack_nframes_t nframes, void *arg) { jack_default_audio_sample_t *out2; jack_default_audio_sample_t *in2; if (process2_activated == 1) { // Reception du process1 pour comparer les donnees in2 = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port2, nframes); for (unsigned int p = 0; p < nframes; p++) { signal2[index2] = in2[p]; if (index2 == 95999) { process2_activated = 0; process1_activated = 0; //index2 = 0; } else { index2++; } } } if (process2_activated == 2) { // envoie de signal1 pour test tie mode et le r�cup�re direct + latence de la boucle jack... out2 = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port2, nframes); in2 = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port2, nframes); for (unsigned int p = 0; p < nframes; p++) { out2[p] = signal1[index1]; index1++; if (index1 == 48000) index1 = 0; signal2[index2] = in2[p]; if (index2 == 95999) { process2_activated = -1; //index2 = 0; } else { index2++; } } } if (process2_activated == 3) { // envoie de -signal1 pour sommation en oppo de phase par jack in2 = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port2, nframes); for (unsigned int p = 0; p < nframes;p++) { signal2[index2] = in2[p]; if (index2 == 95999) { process2_activated = 0; process1_activated = 0; //index2 = 0; } else { index2++; } } } return 0; } // Alternate thread model static int _process (jack_nframes_t nframes) { jack_default_audio_sample_t *in, *out; in = (jack_default_audio_sample_t *)jack_port_get_buffer (input_port1, nframes); out = (jack_default_audio_sample_t *)jack_port_get_buffer (output_port1, nframes); memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes); return 0; } static void* jack_thread(void *arg) { jack_client_t* client = (jack_client_t*) arg; jack_nframes_t last_thread_time = jack_frame_time(client); while (1) { jack_nframes_t frames = jack_cycle_wait(client); jack_nframes_t current_thread_time = jack_frame_time(client); jack_nframes_t delta_time = current_thread_time - last_thread_time; Log("jack_thread : delta_time = %ld\n", delta_time); int status = _process(frames); last_thread_time = current_thread_time; jack_cycle_signal (client, status); } return 0; } // To test callback exiting int process3(jack_nframes_t nframes, void *arg) { static int process3_call = 0; if (process3_call++ > 10) { Log("process3 callback : exiting...\n"); return -1; } else { Log("calling process3 callback : process3_call = %ld\n", process3_call); return 0; } } int process4(jack_nframes_t nframes, void *arg) { jack_client_t* client = (jack_client_t*) arg; static jack_nframes_t last_time = jack_frame_time(client); static jack_nframes_t tolerance = (jack_nframes_t)(cur_buffer_size * 0.1f); jack_nframes_t cur_time = jack_frame_time(client); jack_nframes_t delta_time = cur_time - last_time; Log("calling process4 callback : jack_frame_time = %ld delta_time = %ld\n", cur_time, delta_time); if (delta_time > 0 && abs((int64_t)delta_time - (int64_t)cur_buffer_size) > (int64_t)tolerance) { printf("!!! ERROR !!! jack_frame_time seems to return incorrect values cur_buffer_size = %d, delta_time = %d tolerance %d\n", cur_buffer_size, delta_time, tolerance); } last_time = cur_time; return 0; } int process5(jack_nframes_t nframes, void *arg) { jack_client_t* client = (jack_client_t*) arg; static jack_nframes_t first_current_frames; static jack_time_t first_current_usecs; static jack_time_t first_next_usecs; static float first_period_usecs; static int res1 = jack_get_cycle_times(client, &first_current_frames, &first_current_usecs, &first_next_usecs, &first_period_usecs); jack_nframes_t current_frames; jack_time_t current_usecs; jack_time_t next_usecs; float period_usecs; int res = jack_get_cycle_times(client, ¤t_frames, ¤t_usecs, &next_usecs, &period_usecs); if (res != 0) { printf("!!! ERROR !!! jack_get_cycle_times fails...\n"); return 0; } Log("calling process5 callback : jack_get_cycle_times delta current_frames = %ld delta current_usecs = %ld delta next_usecs = %ld period_usecs = %f\n", current_frames - first_current_frames, current_usecs - first_current_usecs, next_usecs - first_next_usecs, period_usecs); first_current_frames = current_frames; first_current_usecs = current_usecs; first_next_usecs = next_usecs; return 0; } static void display_transport_state() { jack_transport_state_t ts; jack_position_t pos; ts = jack_transport_query(client2, &pos); switch (ts) { case JackTransportStopped: Log("Transport is stopped...\n"); break; case JackTransportRolling: Log("Transport is rolling...\n"); break; case JackTransportLooping: Log("Transport is looping...\n"); break; case JackTransportStarting: Log("Transport is starting...\n"); break; case JackTransportNetStarting: Log("Transport is starting with network sync...\n"); break; } } /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* MAIN FUNCTION *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* */ int main (int argc, char *argv[]) { const char **inports; // array of PHY input/output const char **outports; // array of PHY input/outputs const char *server_name = NULL; const char **connexions1; const char **connexions2; jack_status_t status; char portname[128] = "port"; char filename[128] = "framefile.ext"; const char *nullportname = ""; int option_index; int opt; int a = 0; // working number for in/out port (PHY)... int test_link = 0; // for testing the "overconnect" function int flag; // flag for ports... int is_mine = 0; // to test jack_port_is_mine function... const char *options = "kRnqvt:"; float ratio; // for speed calculation in freewheel mode jack_options_t jack_options = JackNullOption; struct option long_options[] = { {"realtime", 0, 0, 'R'}, {"non-realtime", 0, 0, 'n'}, {"time", 0, 0, 't'}, {"quiet", 0, 0, 'q'}, {"verbose", 0, 0, 'v'}, {"transport", 0, 0, 'k'}, {0, 0, 0, 0} }; client_name1 = "jack_test"; time_to_run = 1; //verbose_mode = 1; //RT = 1; while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { case 'k': transport_mode = 0; break; case 'q': silent_error = 1; break; case 'v': verbose_mode = 1; printf("Verbose mode is activated...\n"); break; case 't': time_to_run = atoi(optarg); break; case 'R': RT = 1; break; default: fprintf (stderr, "unknown option %c\n", opt); usage (); } } if (RT) { printf("Jack server is said being in realtime mode...\n"); } else { printf("Jack server is said being in non-realtime mode...\n"); } /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* init signal data for test *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* */ framecollect = (FrameTimeCollector *) malloc(800 * sizeof(FrameTimeCollector)); signal1 = (jack_default_audio_sample_t *) malloc(48000 * sizeof(jack_default_audio_sample_t)); signal2 = (jack_default_audio_sample_t *) malloc(96000 * sizeof(jack_default_audio_sample_t)); signal1[0] = 0; int p; for (p = 1; p < 48000;p++) { signal1[p] = (float)(sin((p * 2 * M_PI * 1000 ) / 48000)); } for (p = 0; p < 95999;p++) { signal2[p] = 0.0 ; } index1 = 0; index2 = 0; /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* begin test *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* */ printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); printf("*-*-*-*-*-*-*-*-*-*-*-*-*-* Start jack server stress test *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); /** * Register a client... * */ Log("Register a client using jack_client_open()...\n"); client1 = jack_client_open(client_name1, jack_options, &status, server_name); if (client1 == NULL) { fprintf (stderr, "jack_client_open() failed, " "status = 0x%2.0x\n", status); if (status & JackServerFailed) { fprintf(stderr, "Unable to connect to JACK server\n"); } exit (1); } if (status & JackServerStarted) { fprintf(stderr, "JACK server started\n"); } /** * Internal client tests... * */ jack_intclient_t intclient; Log("trying to load the \"inprocess\" server internal client \n"); intclient = jack_internal_client_load (client1, "inprocess", (jack_options_t)(JackLoadName|JackLoadInit), &status, "inprocess", ""); if (intclient == 0 || status & JackFailure) { printf("!!! ERROR !!! cannot load internal client \"inprocess\" intclient 0x%llX status 0x%2.0x !\n", (unsigned long long)intclient, status); } else { Log("\"inprocess\" server internal client loaded\n"); char* internal_name = jack_get_internal_client_name(client1, intclient); if (strcmp(internal_name, "inprocess") == 0) { Log("jack_get_internal_client_name returns %s\n", internal_name); } else { printf("!!! ERROR !!! jack_get_internal_client_name returns incorrect name %s\n", internal_name); } jack_intclient_t intclient1 = jack_internal_client_handle(client1, "inprocess", &status); if (intclient1 == intclient) { Log("jack_internal_client_handle returns correct handle\n"); } else { printf("!!! ERROR !!! jack_internal_client_handle returns incorrect handle 0x%llX\n", (unsigned long long)intclient1); } // Unload internal client status = jack_internal_client_unload (client1, intclient); if (status == 0) { Log("jack_internal_client_unload done first time returns correct value\n"); } else { printf("!!! ERROR !!! jack_internal_client_unload returns incorrect value 0x%2.0x\n", status); } // Unload internal client second time status = jack_internal_client_unload (client1, intclient); if (status & JackFailure && status & JackNoSuchClient) { Log("jack_internal_client_unload done second time returns correct value\n"); } else { printf("!!! ERROR !!! jack_internal_client_unload returns incorrect value 0x%2.0x\n", status); } } /** * try to register another one with the same name... * */ Log("trying to register a new jackd client with name %s using jack_client_new()...\n", client_name1); client2 = jack_client_new(client_name1); if (client2 == NULL) { Log ("valid : a second client with the same name cannot be registered\n"); } else { printf("!!! ERROR !!! Jackd server has accepted multiples client with the same name !\n"); jack_client_close(client2); } /** * try to register another one with the same name using jack_client_open ==> since JackUseExactName is not used, an new client should be opened... * */ Log("trying to register a new jackd client with name %s using jack_client_open()...\n", client_name1); client2 = jack_client_open(client_name1, jack_options, &status, server_name); if (client2 != NULL) { Log ("valid : a second client with the same name can be registered (client automatic renaming)\n"); jack_client_close(client2); } else { printf("!!! ERROR !!! Jackd server automatic renaming feature does not work!\n"); } /** * try to register a client with maximum possible client name size * */ char client_name3[jack_client_name_size()]; // "jack_client_name_size" - 1 effective characters for (int i = 0; i < jack_client_name_size() - 1; i++) { client_name3[i] = 'A'; } // And last one is the terminating '0' client_name3[jack_client_name_size()] = 0; Log("trying to register a new jackd client with maximum possible client name size...\n", client_name3); client2 = jack_client_open(client_name3, jack_options, &status, server_name); if (client2 != NULL) { Log ("valid : a client with maximum possible client name size can be opened\n"); jack_client_close(client2); } else { printf("!!! ERROR !!! opening a client with maximum possible client name size does not work!\n"); } /** * testing client name... * Verify that the name sended at registration and the one returned by jack server is the same... * */ Log("Testing name..."); client_name2 = jack_get_client_name(client1); if (strcmp(client_name1, client_name2) == 0) { Log(" ok\n"); } else { printf("\n!!! ERROR !!! name returned different from the one given : %s\n", client_name2); } /** * Test RT mode... * verify if the real time mode returned by jack match the optional argument defined when launching jack_test*/ if (jack_is_realtime(client1) == RT) { Log("Jackd is in realtime mode (RT = %i).\n", RT); } else { printf("!!! ERROR !!! Jackd is in a non-expected realtime mode (RT = %i).\n", RT); } /** * Register all callbacks... * */ if (jack_set_thread_init_callback(client1, Jack_Thread_Init_Callback, 0) != 0) { printf("!!! ERROR !!! while calling jack_set_thread_init_callback()...\n"); } if (jack_set_freewheel_callback(client1, Jack_Freewheel_Callback, 0) != 0 ) { printf("\n!!! ERROR !!! while calling jack_set_freewheel_callback()...\n"); } if (jack_set_process_callback(client1, process1, 0) != 0) { printf("Error when calling jack_set_process_callback() !\n"); } jack_on_shutdown(client1, jack_shutdown, 0); if (jack_on_info_shutdown) { jack_on_info_shutdown(client1, jack_info_shutdown, 0); } if (jack_set_buffer_size_callback(client1, Jack_Update_Buffer_Size, 0) != 0) { printf("Error when calling buffer_size_callback !\n"); } if (jack_set_graph_order_callback(client1, Jack_Graph_Order_Callback, 0) != 0) { printf("Error when calling Jack_Graph_Order_Callback() !\n"); } if (jack_set_port_rename_callback(client1, Jack_Port_Rename_Callback, 0) != 0 ) printf("\n!!! ERROR !!! while calling jack_set_rename_callback()...\n"); if (jack_set_xrun_callback(client1, Jack_XRun_Callback, 0 ) != 0) { printf("Error when calling jack_set_xrun_callback() !\n"); } if (jack_set_sample_rate_callback(client1, Jack_Sample_Rate_Callback, 0 ) != 0) { printf("Error when calling Jack_Sample_Rate_Callback() !\n"); } if (jack_set_port_registration_callback(client1, Jack_Port_Register, 0) != 0) { printf("Error when calling jack_set_port_registration_callback() !\n"); } if (jack_set_port_connect_callback(client1, Jack_Port_Connect, 0) != 0) { printf("Error when calling jack_set_port_connect_callback() !\n"); } if (jack_set_client_registration_callback(client1, Jack_Client_Registration_Callback, 0) != 0) { printf("Error when calling jack_set_client_registration_callback() !\n"); } jack_set_error_function(Jack_Error_Callback); /** * Create file for clock "frame time" analysis * */ cur_buffer_size = jack_get_buffer_size(client1); sprintf (filename, "framefile-%i.dat", cur_buffer_size); file = fopen(filename, "w"); if (file == NULL) { fprintf(stderr, "Error when opening framefile.dat log file"); exit(-1); } /** * Try to register a client with a NULL name/zero length name... * */ output_port1 = jack_port_register(client1, nullportname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (output_port1 == NULL) { Log("Can't register a port with a NULL portname... ok.\n"); } else { printf("!!! ERROR !!! Can register a port with a NULL portname !\n"); jack_port_unregister(client1, output_port1); } /** * Register 1 port in order to stress other functions. * */ output_port1 = jack_port_register(client1, portname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (output_port1 == NULL) { printf("!!! ERROR !!! Can't register any port for the client !\n"); exit(1); } /** * Test port type of the just registered port. * */ if (strcmp(jack_port_type(output_port1), JACK_DEFAULT_AUDIO_TYPE) != 0) { printf("!!! ERROR !!! jack_port_type returns an incorrect value!\n"); } else { Log("Checking jack_port_type()... ok.\n"); } /** * Try to register another port with the same name... * */ output_port2 = jack_port_register(client1, portname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (output_port2 == NULL) { Log("Can't register two ports with the same name... ok\n"); } else { if (strcmp (jack_port_name(output_port1), jack_port_name(output_port2)) == 0) { printf("!!! ERROR !!! Can register two ports with the same name ! (%px : %s & %px : %s).\n", output_port1, jack_port_name(output_port1), output_port2, jack_port_name(output_port2)); jack_port_unregister(client1, output_port2); } else { Log("Can't register two ports with the same name... ok (auto-rename %s into %s).\n", jack_port_name(output_port1), jack_port_name(output_port2)); jack_port_unregister(client1, output_port2); } } /** * Verify that both port_name and port_short_name return correct results... * */ sprintf (portname, "%s:%s", jack_get_client_name(client1), jack_port_short_name(output_port1)); if (strcmp(jack_port_name(output_port1), portname) != 0) { printf("!!! ERROR !!! functions jack_port_name and/or jack_short_port_name seems to be invalid !\n"); printf("client_name = %s\n short_port_name = %s\n port_name = %s\n", jack_get_client_name(client1), jack_port_short_name(output_port1), jack_port_name(output_port1)); } /** * Verify the function port_set_name * */ if (jack_port_set_name (output_port1, "renamed-port#") == 0 ) { if (strcmp(jack_port_name(output_port1), "renamed-port#") == 0) { printf("!!! ERROR !!! functions jack_port_set_name seems to be invalid !\n"); printf("jack_port_name return '%s' whereas 'renamed-port#' was expected...\n", jack_port_name(output_port1)); } else { Log("Checking jack_port_set_name()... ok\n"); jack_port_set_name (output_port1, "port"); } } else { printf("error : port_set_name function can't be tested...\n"); } /** * Verify if a port can be registered with maximum port name size (that is "short name") * */ int short_port_size_max = jack_port_name_size() - jack_client_name_size() - 1; // Port is of shape: "client_name:port_name" char port_name3[short_port_size_max]; // "short_port_size_max" - 1 effective characters for (int i = 0; i < short_port_size_max - 1; i++) { port_name3[i] = 'A'; } // And last one is the terminating '0' port_name3[short_port_size_max] = 0; jack_port_t * test_max_port = jack_port_register(client1, port_name3, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (test_max_port != NULL) { Log ("valid : a port with maximum possible port name size can be registered\n"); jack_port_unregister(client1, test_max_port); } else { printf("!!! ERROR !!! registering a port with maximum possible port name size does not work!\n"); } port_callback_reg = 0; // number of port registration received by the callback /** * Activate the client * */ if (jack_activate(client1) < 0) { printf ("Fatal error : cannot activate client1\n"); exit(1); } /** * Test if port rename callback have been called. * */ jack_port_set_name (output_port1, "renamed-port#"); jack_sleep(1 * 1000); if (port_rename_clbk == 0) { printf("!!! ERROR !!! Jack_Port_Rename_Callback was not called !!.\n"); } /** * Test if port registration callback have been called. * */ jack_sleep(1 * 1000); // To hope all port registration and reorder callback have been received... if (1 == port_callback_reg) { Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", 1, port_callback_reg); } else { printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", 1, port_callback_reg); } /** * Test if init callback initThread have been called. * */ if (init_clbk == 0) { printf("!!! ERROR !!! Jack_Thread_Init_Callback was not called !!.\n"); } jack_sleep(10 * 1000); // test see the clock in the graph at the begining... /** * Stress Freewheel mode... * Try to enter freewheel mode. Check the realtime mode de-activation. * Check that the number of call of the process callback is greater than in non-freewheel mode. * Give an approximated speed ratio (number of process call) between the two modes. * Then return in normal mode. */ t_error = 0; activated = 0; jack_sleep(1 * 1000); count1 = activated; Log("Testing activation freewheel mode...\n"); linefw = linecount; // count for better graph reading with gnuplot jack_set_freewheel(client1, 1); activated = 0; jack_sleep(1 * 1000); count2 = activated; if (jack_is_realtime(client1) == 0) { t_error = 0; } else { printf("\n!!! ERROR !!! RT mode is always activated while freewheel mode is applied !\n"); t_error = 1; } if (activated == 0) { printf("!!! ERROR !!! Freewheel mode doesn't activate audio callback !!\n"); } jack_set_freewheel(client1, 0); jack_sleep(7 * 1000); if (jack_is_realtime(client1) == 1) { } else { printf("\n!!! ERROR !!! freewheel mode fail to reactivate RT mode when exiting !\n"); t_error = 1; } if (t_error == 0) { Log("Freewheel mode appears to work well...\n"); } if (count1 == 0) { Log("Audio Callback in 'standard' (non-freewheel) mode seems not to be called...\n"); Log("Ratio speed would be unavailable...\n"); } else { ratio = (float) ((count2 - count1) / count1); Log("Approximative speed ratio of freewheel mode = %f : 1.00\n", ratio); } /** * Stress buffer function... * get current buffer size. * Try to apply a new buffer size value ( 2 x the precedent buffer size value) * Then return in previous buffer size mode. * */ float factor = 0.5f; old_buffer_size = jack_get_buffer_size(client1); Log("Testing BufferSize change & Callback...\n--> Current buffer size : %d.\n", old_buffer_size); linebuf = linecount; if (jack_set_buffer_size(client1, (jack_nframes_t)(old_buffer_size * factor)) < 0) { printf("!!! ERROR !!! jack_set_buffer_size fails !\n"); } jack_sleep(1 * 1000); cur_buffer_size = jack_get_buffer_size(client1); if (abs((old_buffer_size * factor) - cur_buffer_size) > 5) { // Tolerance needed for dummy driver... printf("!!! ERROR !!! Buffer size has not been changed !\n"); printf("!!! Maybe jack was compiled without the '--enable-resize' flag...\n"); } else { Log("jack_set_buffer_size() command successfully applied...\n"); } jack_sleep(3 * 1000); jack_set_buffer_size(client1, old_buffer_size); cur_buffer_size = jack_get_buffer_size(client1); /** * Test the last regestered port to see if port_is_mine function the right value. * A second test will be performed later. * The result will be printed at the end. * */ if (jack_port_is_mine(client1, output_port1)) { is_mine = 1; } else { is_mine = 0; } /** * Check that the ID returned by the port_by_name is right. * (it seems there is a problem here in some jack versions). * */ if (output_port1 != jack_port_by_name(client1, jack_port_name(output_port1))) { printf("!!! ERROR !!! function jack_port_by_name() return bad value !\n"); printf("!!! jack_port_by_name(jack_port_name(_ID_) ) != _ID_returned_at_port_registering ! (%px != %px)\n", jack_port_by_name(client1, jack_port_name(output_port1)), output_port1); } else { Log("Checking jack_port_by_name() return value... ok\n"); } if (NULL != jack_port_by_name(client1, jack_port_short_name(output_port1))) { printf("!!! ERROR !!! function jack_port_by_name() return a value (%px) while name is incomplete !\n", jack_port_by_name(client1, jack_port_short_name(output_port1))); } else { Log("Checking jack_port_by_name() with bad argument... ok (returned id 0)\n"); } /** * remove the output port previously created * no more ports should subsist here for our client. * */ if (jack_port_unregister(client1, output_port1) != 0) { printf("!!! ERROR !!! while unregistering port %s.\n", jack_port_name(output_port1)); } /** * list all in ports * */ inports = jack_get_ports(client1, NULL, NULL, 0); /** * Test the first PHY (physical) connection to see if it's "mine". * and report the result in the test that began before. * The result is printed later. * */ if (jack_port_is_mine(client1, jack_port_by_name(client1, inports[0]))) { is_mine = 0; } /** * List all devices' flags and print them... * */ Log("\nTry functions jack_get_ports, jack_port_flag & jack_port_by_name to list PHY devices...\n"); Log("-----------------------------------------------------------\n"); Log("---------------------------DEVICES-------------------------\n"); Log("-----------------------------------------------------------\n"); a = 0; while (inports[a] != NULL) { flag = jack_port_flags(jack_port_by_name(client1, inports[a]) ); Log(" * %s (id : %i)\n", inports[a], jack_port_by_name(client1, inports[a])); Log(" ("); if (flag & JackPortIsInput) Log("JackPortIsInput "); if (flag & JackPortIsOutput) Log("JackPortIsOutput "); if (flag & JackPortIsPhysical) Log("JackPortIsPhysical "); if (flag & JackPortCanMonitor) Log("JackPortCanMonitor "); if (flag & JackPortIsTerminal) Log("JackPortIsTerminal "); Log(")\n\n"); a++; } Log("-----------------------------------------------------------\n\n"); /** * list all PHY in/out ports... * This list will be used later many times. * */ outports = jack_get_ports(client1, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); inports = jack_get_ports(client1, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (outports == NULL) { printf("!!! WARNING !!! no physical capture ports founded !\n"); } if (inports == NULL) { printf("!!! WARNING !!! no physical output ports founded !\n"); } /** * Brute test : try to create as many ports as possible. * It stops when jack returns an error. * Then try to connect each port to physical entry... * Check also that graph reorder callback is called. * */ Log("Registering as many ports as possible and connect them to physical entries...\n"); lineports = linecount; t_error = 0; i = 0; // number of couple 'input-ouput' j = 0; // number of ports created port_callback_reg = 0; // number of port registration received by the callback reorder = 0; // number of graph reorder callback activation test_link = 0 ; // Test the "overconnect" function only one time while (t_error == 0) { sprintf (portname, "input_%d", i); input_port1 = jack_port_register(client1, portname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); j++; if (input_port1 == NULL) { j--; t_error = 1; } else { // Connect created input to PHY output a = 0; while (outports && outports[a] != NULL) { if (jack_connect(client1, outports[a], jack_port_name(input_port1))) { printf ("error : cannot connect input PHY port to client port %s\n", jack_port_name(input_port1)); } else { // printf ("input PHY port %s connected to client port %s\n", outports[a], jack_port_name(input_port1)); } a++; } // Try one time to "overconnect" 2 ports (the latest created)... if (test_link == 0 && outports && ((a - 1) > 0) && outports[a - 1]) { if (jack_connect(client1, outports[a - 1], jack_port_name(input_port1)) == EEXIST) { // cannot over-connect input PHY port to client port. ok. test_link = 1; } } } sprintf(portname, "output_%d", i); output_port1 = jack_port_register(client1, portname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); j++; if (output_port1 == NULL) { t_error = 1; j--; } else { // Connect created input to PHY output a = 0; while (inports && inports[a] != NULL) { if (jack_connect(client1, jack_port_name(output_port1), inports[a])) { printf ("error : cannot connect input PHY port %s to client port %s\n", inports[a], jack_port_name(output_port1)); } else { // output PHY port %s connected to client port. ok. } a++; } // Try one time to "overconnect" 2 ports (the latest created)... if (test_link == 0 && inports && ((a - 1) > 0) && inports[a - 1]) { if (jack_connect(client1, jack_port_name(output_port1), inports[a - 1]) == EEXIST) { // cannot over-connect output PHY port to client port. ok. test_link = 1; } } } i++; } jack_sleep(1 * 1000); // To hope all port registration and reorder callback have been received... // Check port registration callback if (j == port_callback_reg) { Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", j, port_callback_reg); } else { printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", j, port_callback_reg); } if (reorder == (2 * j)) { Log("%i graph reorder callback have been received... ok\n", reorder); } else { printf("!!! ERROR !!! %i graph reorder callback have been received (maybe non-valid value)...\n", reorder); } /** * print basic test connection functions result ... * over-connected means here that we try to connect 2 ports that are already connected. * */ if (test_link) { Log("Jack links can't be 'over-connected'... ok\n"); } else { printf("!!! ERROR !!! Jack links can be 'over-connected'...\n"); } /** * Print the result of the two jack_is_mine test. * */ if (is_mine == 1) { Log("Checking jack_port_is_mine()... ok\n"); } else { printf("!!! ERROR !!! jack_port_is_mine() function seems to send non-valid datas !\n"); } /** * Free the array of the physical input and ouput ports. * (as mentionned in the doc of jack_get_ports) * */ jack_free(inports); jack_free(outports); /** * Try to "reactivate" the client whereas it's already activated... * */ if (jack_activate(client1) < 0) { printf("!!! ERROR !!! Cannot activate client1 a second time...\n"); exit(1); } else { Log("jackd server accept client.jack_activate() re-activation (while client was already activated).\n"); } /** * Deregister all ports previously created. * */ port_callback_reg = 0; // to check registration callback Log("Deregistering all ports of the client...\n"); inports = jack_get_ports(client1, NULL, NULL, 0); a = 0; while (inports[a] != NULL) { flag = jack_port_flags(jack_port_by_name(client1, inports[a])); input_port1 = jack_port_by_name(client1, inports[a]); if (jack_port_is_mine(client1, input_port1)) { if (jack_port_unregister(client1, input_port1) != 0) { printf("!!! ERROR !!! while unregistering port %s.\n", jack_port_name(output_port1)); } } a++; } jack_sleep(1 * 1000); // To hope all port registration and reorder callback have been received... // Check port registration callback again if (j == port_callback_reg) { Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", j, port_callback_reg); } else { printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", j, port_callback_reg); } jack_free(inports); // free array of ports (as mentionned in the doc of jack_get_ports) /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* Open a new client (second one) to test some other things... *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* */ Log("\n\n----------------------------------------------------------------------\n"); Log("Starting second new client 'jack_test_#2'...\n"); /* open a client connection to the JACK server */ client_name2 = "jack_test_#2"; linecl2 = linecount; // reminders for graph analysis client2 = jack_client_new(client_name2); if (client2 == NULL) { fprintf(stderr, "jack_client_new() failed for %s.\n" "status = 0x%2.0x\n", client_name2, status); if (status & JackServerFailed) { fprintf(stderr, "Unable to connect client2 to JACK server\n"); } exit(1); } // Check client registration callback after jack_client_new jack_sleep(2000); if (client_register == 0) { printf("!!! ERROR !!! Client registration callback not called for an opened client !\n"); } // Check client registration callback after jack_client_close jack_client_close(client2); jack_sleep(2000); if (client_register == 1) { printf("!!! ERROR !!! Client registration callback not called for a closed client!\n"); } // Open client2 again... client2 = jack_client_new(client_name2); /** * Register callback for this client. * Callbacks are the same as the first client for most of them, excepted for process audio callback. * */ jack_set_port_registration_callback(client2, Jack_Port_Register, 0); jack_set_process_callback(client2, process2, 0); jack_on_shutdown(client2, jack_shutdown, 0); /** * Register one input and one output for each client. * */ Log("registering 1 input/output ports for each client...\n"); output_port1 = jack_port_register(client1, "out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); output_port2 = jack_port_register(client2, "out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); input_port1 = jack_port_register(client1, "in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); input_port2 = jack_port_register(client2, "in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); if ((output_port1 == NULL) || (output_port2 == NULL) || (input_port1 == NULL) || (input_port2 == NULL)) { printf("!!! ERROR !!! Unable to register ports...\n"); } /** * Set each process mode to idle and activate client2 * */ process2_activated = -1; process1_activated = -1; if (jack_activate(client2) < 0) { printf("Fatal error : cannot activate client2\n"); exit(1); } /** * Connect the two clients and check that all connections are well-done. * */ Log("Testing connections functions between clients...\n"); if (jack_connect(client1, jack_port_name(output_port1), jack_port_name(input_port2)) != 0) { printf("!!! ERROR !!! while client1 intenting to connect ports...\n"); } if (jack_connect(client2, jack_port_name(output_port2), jack_port_name(input_port1)) != 0) { printf("!!! ERROR !!! while client2 intenting to connect ports...\n"); } if (jack_connect(client1, jack_port_name(output_port1), jack_port_name(input_port1)) != 0) { printf("!!! ERROR !!! while client1 intenting to connect ports...\n"); } /** * Test the port_connected function... * */ if ((jack_port_connected(output_port1) == jack_port_connected(input_port1)) && (jack_port_connected(output_port2) == jack_port_connected(input_port2)) && (jack_port_connected(output_port2) == 1) && (jack_port_connected(output_port1) == 2) ) { Log("Checking jack_port_connected()... ok.\n"); } else { printf("!!! ERROR !!! function jack_port_connected() return a bad value !\n"); printf("jack_port_connected(output_port1) %d\n", jack_port_connected(output_port1)); printf("jack_port_connected(output_port2) %d\n", jack_port_connected(output_port2)); printf("jack_port_connected(input_port1) %d\n", jack_port_connected(input_port1)); printf("jack_port_connected(input_port2) %d\n", jack_port_connected(input_port2)); } /** * Test a new time the port_by_name function...(now we are in multi-client mode) * */ Log("Testing again jack_port_by_name...\n"); if (output_port1 != jack_port_by_name(client1, jack_port_name(output_port1))) { printf("!!! ERROR !!! function jack_port_by_name() return bad value in a multi-client application!\n"); printf("!!! jack_port_by_name(jack_port_name(_ID_) ) != _ID_ in multiclient application.\n"); } else { Log("Checking jack_port_by_name() function with a multi-client application... ok\n"); } /** * Test the port_connected_to function... * */ if ((jack_port_connected_to (output_port1, jack_port_name(input_port2))) && (!(jack_port_connected_to (output_port2, jack_port_name(input_port2))))) { Log("checking jack_port_connected_to()... ok\n"); } else { printf("!!! ERROR !!! jack_port_connected_to() return bad value !\n"); } /** * Test the port_get_connections & port_get_all_connections functions... * */ Log("Testing jack_port_get_connections and jack_port_get_all_connections...\n"); a = 0; t_error = 0; connexions1 = jack_port_get_connections (output_port1); connexions2 = jack_port_get_all_connections(client1, output_port1); if ((connexions1 == NULL) || (connexions2 == NULL)) { printf("!!! ERROR !!! port_get_connexions or port_get_all_connexions return a NULL pointer !\n"); } else { while ((connexions1[a] != NULL) && (connexions2[a] != NULL) && (t_error == 0)) { t_error = strcmp(connexions1[a], connexions2[a]); a++; } if (t_error == 0) { Log("Checking jack_port_get_connections Vs jack_port_get_all_connections... ok\n"); } else { printf("!!! ERROR !!! while checking jack_port_get_connections Vs jack_port_get_all_connections...\n"); } } a = 0; t_error = 0; inports = jack_get_ports(client1, NULL, NULL, JackPortIsPhysical | JackPortIsInput); connexions1 = NULL; if (inports && inports[0] != NULL) { connexions1 = jack_port_get_connections (jack_port_by_name(client1, inports[0])); connexions2 = jack_port_get_all_connections(client1, jack_port_by_name(client1, inports[0])); } jack_free (inports); if (connexions1 == NULL) { Log("checking jack_port_get_connections() for external client... ok\n"); } else { while ((connexions1[a] != NULL) && (connexions2[a] != NULL) && (t_error == 0)) { t_error = strcmp(connexions1[a], connexions2[a]); a++; } } if (t_error == 0) { Log("Checking jack_port_get_connections() Vs jack_port_get_all_connections() on PHY port... ok\n"); } else { printf("!!! ERROR !!! while checking jack_port_get_connections() Vs jack_port_get_all_connections() on PHY port...\n"); } if (jack_disconnect(client1, jack_port_name(output_port1), jack_port_name(input_port1)) != 0) { printf("!!! ERROR !!! while client1 intenting to disconnect ports...\n"); } if (jack_disconnect(client1, jack_port_name(output_port2), jack_port_name(input_port1)) != 0) { printf("!!! ERROR !!! while client1 intenting to disconnect ports...\n"); } // No links should subsist now... /** * Checking data connexion * establishing a link between client1.out1 --> client2.in2 * Send the signal1 test on out1. Record the result into signal2. (see process functions). ---------------------------------------------------------------------------*/ Log("Testing connections datas between clients...\n"); jack_connect(client2, jack_port_name(output_port1), jack_port_name(input_port2) ); process2_activated = -1; process1_activated = -1; Log("process 2 : idle mode...\n"); Log("Sending datas..."); index1 = 0; index2 = 0; process1_activated = 1; // We start emitting first. process2_activated = 1; // So record begin at least when we just begin to emitt the signal, else at next call of process with // nframe = jack buffersize shifting. while (process2_activated == 1) { jack_sleep(1 * 1000); Log("."); } index2 = 0; Log("\nAnalysing datas...\n"); // search the first occurence of the first element of the reference signal in the recorded signal while (signal2[index2] != signal1[1] ) { index2++; if (index2 == 95999) { printf("!!! ERROR !!! Data not found in first connexion data check!\n"); break; } } index1 = index2; Log("Data founded at offset %i.\n", index2); // And now we founded were the recorded data are, we can see if the two signals matches... while ( (signal2[index2] == signal1[index2 - index1 + 1]) || (index2 == 95999) || ((index2 - index1 + 1) == 47999) ) { index2++; } Log("Checking difference between datas... %i have the same value...\n", index2 - index1); if ((index2 - index1) == 48000) { Log("Data received are valid...\n"); } else { printf("!!! ERROR !!! data transmission seems not to be valid in first connexion data check!\n"); } if (jack_disconnect(client1, jack_port_name(output_port1), jack_port_name(input_port2) ) != 0) // no more connection between ports exist now... { printf("Error while establishing new connexion (disconnect).\n"); } /** * Test TIE MODE * (This mode seems to be problematic in standard jack version 0.100. It seems that nobody * is used to apply this mode because the tie mode doesn't work at all. A patch seems difficult to produce * in this version of jack. Tie mode work well in MP version.) * Test some basic thinks (tie with 2 differents client, tie non-owned ports...) * Tie client1.in1 and client1.out1 ports, and make some data test to check the validity of the tie. * */ Log("Testing tie mode...\n"); if (jack_port_tie(input_port1, output_port2) != 0) { Log("not possible to tie two ports from two differents clients... ok\n"); } else { printf("!!! ERROR !!! port_tie has allowed a connexion between two differents clients !\n"); jack_port_untie(output_port2); } Log("Testing connections datas in tie mode...\n"); int g; for (g = 0; g < 96000; g++) signal2[g] = 0.0; // Create a loop (emit test) client2.out2----client.in1--tie--client1.out1-----client2.in1 (receive test) if (jack_port_tie(input_port1, output_port1) != 0) { printf("Unable to tie... fatal error : data test will not be performed on tie mode !!\n"); } else { // begin of tie if (jack_connect(client1, jack_port_name(output_port1), jack_port_name(input_port2)) != 0) { printf("!!! ERROR !!! while client1 intenting to connect ports...\n"); } if (jack_connect(client1, jack_port_name(output_port2), jack_port_name(input_port1)) != 0) { printf("!!! ERROR !!! while client1 intenting to connect ports...\n"); } process1_activated = -1; process2_activated = -1; // We can manualy check here that the tie is effective. // ie : playing a wav with a client, connecting ports manualy with qjackctl, and listen... // printf("manual test\n"); // jack_sleep(50); // printf("end of manual test\n"); index1 = 0; index2 = 0; process1_activated = -1; process2_activated = 2; Log("Sending datas..."); while (process2_activated == 2) { jack_sleep(1 * 1000); Log("."); } process1_activated = -1; process2_activated = -1; index2 = 0; Log("\nAnalysing datas...\n"); // We must find at least 2 identical values to ensure we are at the right place in the siusoidal array... while (!((signal2[index2] == signal1[1]) && (signal2[index2 + 1] == signal1[2]))) { index2++; if (index2 == 95999) { printf("!!! ERROR !!! Data not found in connexion check of tie mode!\n"); break; } } index1 = index2; Log("Tie mode : Data founded at offset %i.\n", index2); while (signal2[index2] == signal1[index2 - index1 + 1]) { index2++; if ((index2 == 95999) || ((index2 - index1 + 1) == 47999)) { break; } } Log("Checking difference between datas... %i have the same value...\n", index2 - index1); if ((index2 - index1) > 47995) { Log("Data received in tie mode are valid...\n"); } else { // in tie mode, the buffers adress should be the same for the two tied ports. printf("!!! ERROR !!! data transmission seems not to be valid !\n"); printf("Links topology : (emitt) client2.out2 ----> client1.in1--(tie)--client1.out1----->client2.in2 (recive)\n"); printf(" port_name : Port_adress \n"); printf(" output_port1 : %px\n", jack_port_get_buffer(output_port1, cur_buffer_size)); printf(" input_port2 : %px\n", jack_port_get_buffer(input_port2, cur_buffer_size)); printf(" output_port2 : %px\n", jack_port_get_buffer(output_port2, cur_buffer_size)); printf(" input_port1 : %px\n", jack_port_get_buffer(input_port1, cur_buffer_size)); } jack_port_untie(output_port1); jack_port_disconnect(client1, output_port2); jack_port_disconnect(client1, output_port1); } //end of tie /** * Testing SUMMATION CAPABILITIES OF JACK CONNECTIONS * * In a short test, we just check a simple summation in jack. * A first client(client1) send two signal in phase opposition * A second client(client2) record the summation at one of his port * So, the result must be zero... * See process1 for details about steps of this test * */ // fprintf(file, "Sum test\n"); Log("Checking summation capabilities of patching...\n"); output_port1b = jack_port_register(client1, "out1b", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); jack_connect(client2, jack_port_name(output_port1), jack_port_name(input_port2)); jack_connect(client2, jack_port_name(output_port1b), jack_port_name(input_port2)); process1_activated = 3; process2_activated = -1; for (g = 0; g < 96000; g++) signal2[g] = 0.0; index1 = 0; index2 = 0; Log("Sending datas..."); process2_activated = 3; while (process2_activated == 3) { jack_sleep(1 * 1000); Log("."); } process1_activated = -1; process2_activated = -1; index2 = 0; Log("\nAnalysing datas...\n"); // same idea as above, with first data check... while (!((signal2[index2] == 0.0 ) && (signal2[(index2 + 1)] == 0.0 ))) { index2++; if (index2 == 95999) { printf("!!! ERROR !!! Data not found in summation check!\n"); break; } } index1 = index2; Log("Data founded at offset %i.\n", index2); while ( signal2[index2] == 0.0 ) { index2++; if ((index2 > 95998) || ((index2 - index1 + 1) > 47998)) { break; } } Log("Checking difference between datas...\n"); if ((index2 - index1) > 47996) { Log("Data mixed received are valid...\nSummation is well done.\n"); } else { printf("!!! ERROR !!! data transmission / summation seems not to be valid !\n"); } jack_port_disconnect(client1, output_port1); jack_port_disconnect(client1, output_port1b); jack_port_unregister(client1, output_port1b); if (jack_port_name(output_port1b) != NULL ) { printf("!!! WARNING !!! port_name return something while the port have been unregistered !\n"); printf("!!! Name of unregistered port : %s !\n", jack_port_name(output_port1b)); } else { Log("Checking jack_port_name() with a non valid port... ok\n"); } if (jack_port_set_name(output_port1b, "new_name") == 0 ) { printf("!!! WARNING !!! An unregistered port can be renamed successfully !\n"); } else { Log("Checking renaming of an unregistered port... ok\n"); } inports = jack_get_ports(client1, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (inports && jack_port_set_name(jack_port_by_name(client1, inports[0]), "new_name") == 0 ) { printf("!!! WARNING !!! A PHYSICAL port can be renamed successfully !\n"); } else { Log("Checking renaming of an unregistered port... ok\n"); } jack_free (inports); /** * Checking latency issues * here are simple latency check * We simply check that the value returned by jack seems ok * Latency compensation is a difficult point. * Actually, jack is not able to see "thru" client to build a full latency chain. * Ardour use theses informations to do internally his compensations. * * 3 test are done : one with no connections between client, one with a serial connection, and one with parallel connection */ Log("Checking about latency functions...\n"); t_error = 0; jack_recompute_total_latencies(client1); Log("jack_recompute_total_latencies...\n"); if ((jack_port_get_latency (output_port1) != 0) || (jack_port_get_total_latency(client1, output_port1) != 0) ) { t_error = 1; printf("!!! ERROR !!! default latency of a non-PHY device is not set to zero !\n"); } inports = jack_get_ports(client1, NULL, NULL, JackPortIsPhysical | JackPortIsInput); outports = jack_get_ports(client1, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); if (inports && outports && inports[0] != NULL && outports[0] != NULL) { output_ext_latency = jack_port_get_latency (jack_port_by_name(client1, inports[0])); // from client to out driver (which has "inputs" ports..) input_ext_latency = jack_port_get_latency (jack_port_by_name(client1, outports[0])); // from in driver (which has "output" ports..) to client if (output_ext_latency != jack_port_get_total_latency(client1, jack_port_by_name(client1, inports[0]))) { t_error = 1; printf("!!! ERROR !!! get_latency & get_all_latency for a PHY device (unconnected) didn't return the same value !\n"); } Log("Checking a serial model with 2 clients...\n"); jack_connect(client1, jack_port_name(output_port1), jack_port_name(input_port2)); jack_connect(client1, outports[0], jack_port_name(input_port1)); jack_connect(client2, jack_port_name(output_port2), inports[0]); jack_port_set_latency(output_port2, 256); jack_recompute_total_latencies(client1); if ((jack_port_get_latency (output_port1) != 0) || (jack_port_get_total_latency(client1, output_port1) != 0) || (jack_port_get_latency (jack_port_by_name(client1, inports[0])) != (output_ext_latency)) || (jack_port_get_total_latency(client1, jack_port_by_name(client1, inports[0])) != (output_ext_latency + 256)) || (jack_port_get_total_latency(client1, output_port2) != (output_ext_latency + 256)) || (jack_port_get_total_latency(client1, input_port2) != 0) || (jack_port_get_total_latency(client1, input_port1) != input_ext_latency) || (jack_port_get_latency (jack_port_by_name(client1, outports[0])) != input_ext_latency) || (jack_port_get_total_latency(client1, jack_port_by_name(client1, outports[0])) != input_ext_latency) ) { printf("!!! WARNING !!! get_latency functions may have a problem : bad value returned !\n"); printf("!!! get_latency(output_port1) : %i (must be 0)\n", jack_port_get_latency(output_port1)); printf("!!! get_total_latency(output_port1) : %i (must be 0)\n", jack_port_get_total_latency(client1, output_port1)); printf("!!! get_latency(PHY[0]) : %i (must be external latency : %i)\n", jack_port_get_latency(jack_port_by_name(client1, inports[0])), output_ext_latency); printf("!!! get_total_latency(PHY[0]) : %i (must be %i)\n", jack_port_get_total_latency(client1, jack_port_by_name(client1, inports[0])) , (output_ext_latency + 256)); printf("!!! get_total_latency(output_port2) : %i (must be %i)\n", jack_port_get_total_latency(client1, output_port2), (output_ext_latency + 256)); printf("!!! get_total_latency(input_port2) : %i (must be 0)\n", jack_port_get_total_latency(client1, input_port2)); printf("!!! get_total_latency(input_port1) : %i (must be %i)\n", jack_port_get_total_latency(client1, input_port1), input_ext_latency); printf("!!! get_latency(PHY[0]) : %i (must be %i)\n", jack_port_get_latency(jack_port_by_name(client1, outports[0])), input_ext_latency); printf("!!! get_total_latency(PHY[0]) : %i (must be %i)\n", jack_port_get_total_latency(client1, jack_port_by_name(client1, outports[0])), input_ext_latency); } else { Log("get_latency & get_total_latency seems quite ok...\n"); } jack_port_disconnect(client1, output_port1); jack_port_disconnect(client1, output_port2); jack_port_disconnect(client1, input_port1); jack_port_disconnect(client1, input_port2); Log("Checking a parallel model with 2 clients...\n"); jack_connect(client2, outports[0], jack_port_name(input_port1)); jack_connect(client2, outports[0], jack_port_name(input_port2)); jack_connect(client2, jack_port_name(output_port1), inports[0]); jack_connect(client2, jack_port_name(output_port2), inports[0]); jack_port_set_latency(output_port1, 256); jack_port_set_latency(output_port2, 512); jack_recompute_total_latencies(client1); if ((jack_port_get_latency(output_port1) != 256 ) || (jack_port_get_total_latency(client1, output_port1) != (256 + output_ext_latency)) || (jack_port_get_latency(output_port2) != 512) || (jack_port_get_total_latency(client1, output_port2) != (512 + output_ext_latency)) || (jack_port_get_latency(jack_port_by_name(client1, inports[0])) != output_ext_latency) || (jack_port_get_total_latency(client1, jack_port_by_name(client1, inports[0])) != (512 + output_ext_latency)) ) { printf("!!! WARNING !!! get_latency functions may have a problem : bad value returned !\n"); printf("!!! get_latency(output_port1) : %i (must be 256)\n", jack_port_get_latency(output_port1)); printf("!!! get_total_latency(output_port1) : %i (must be 256 + output_ext_latency)\n", jack_port_get_total_latency(client1, output_port1)); printf("!!! get_latency(output_port2) : %i (must 512)\n", jack_port_get_latency(output_port2)); printf("!!! get_total_latency(output_port2) : %i (must 512 + output_ext_latency)\n", jack_port_get_total_latency(client1, output_port2)); printf("!!! get_latency(inports[0])) : %i (must output_ext_latency)\n", jack_port_get_latency(jack_port_by_name(client1, inports[0]))); printf("!!! get_total_latency(inports[0]) : %i (must 512 + output_ext_latency)\n", jack_port_get_total_latency(client1, jack_port_by_name(client1, inports[0]))); } else { Log("get_latency & get_total_latency seems quite ok...\n"); } } else { printf("No physical port founded : not able to test latency functions..."); } jack_port_disconnect(client1, input_port1); jack_port_disconnect(client1, input_port2); jack_port_disconnect(client1, output_port1); jack_port_disconnect(client1, output_port2); jack_sleep(1000); jack_free(inports); jack_free(outports); /** * Checking transport API. * Simple transport test. * Check a transport start with a "slow" client, simulating a delay around 1 sec before becoming ready. * */ Log("-----------------------------------------------------------\n"); Log("---------------------------TRANSPORT-----------------------\n"); Log("-----------------------------------------------------------\n"); lineports = linecount; if (transport_mode) { int wait_count; ts = jack_transport_query(client1, &pos); if (ts == JackTransportStopped) { Log("Transport is stopped...\n"); } else { jack_transport_stop(client1); Log("Transport state : %i\n", ts); } if (jack_set_sync_callback(client2, Jack_Sync_Callback, 0) != 0) { printf("error while calling set_sync_callback...\n"); } Log("starting transport...\n"); starting_state = 1; // Simulate starting state jack_transport_start(client1); // Wait until sync callback is called while (!(sync_called)) { jack_sleep(1 * 1000); } // Wait untill rolling : simulate sync time out Log("Simulate a slow-sync client exceeding the time-out\n"); wait_count = 0; do { jack_sleep(100); // Wait 100 ms each cycle wait_count++; if (wait_count == 100) { Log("!!! ERROR !!! max time-out exceedeed : sync time-out does not work correctly\n"); break; } ts = jack_transport_query(client2, &pos); Log("Waiting....pos = %ld\n", pos.frame); display_transport_state(); } while (ts != JackTransportRolling); Log("Sync callback have been called %i times.\n", sync_called); jack_transport_stop(client1); // Wait until stopped ts = jack_transport_query(client2, &pos); while (ts != JackTransportStopped) { jack_sleep(1 * 1000); ts = jack_transport_query(client2, &pos); } // Simulate starting a slow-sync client that rolls after 0.5 sec Log("Simulate a slow-sync client that needs 0.5 sec to start\n"); sync_called = 0; wait_count = 0; starting_state = 1; // Simulate starting state Log("Starting transport...\n"); jack_transport_start(client1); display_transport_state(); Log("Waiting 0.5 sec...\n"); jack_sleep(500); starting_state = 0; // Simulate end of starting state after 0.5 sec // Wait untill rolling ts = jack_transport_query(client2, &pos); while (ts != JackTransportRolling) { jack_sleep(100); // Wait 100 ms each cycle wait_count++; if (wait_count == 10) { Log("!!! ERROR !!! starting a slow-sync client does not work correctly\n"); break; } ts = jack_transport_query(client2, &pos); } if (sync_called == 0) { Log("!!! ERROR !!! starting a slow-sync client does not work correctly\n"); } Log("Sync callback have been called %i times.\n", sync_called); display_transport_state(); // Test jack_transport_locate while rolling Log("Test jack_transport_locate while rolling\n"); ts = jack_transport_query(client2, &pos); Log("Transport current frame = %ld\n", pos.frame); jack_nframes_t cur_frame = pos.frame; wait_count = 0; do { display_transport_state(); jack_sleep(10); // 10 ms // locate at first... wait_count++; if (wait_count == 1) { Log("Do jack_transport_locate\n"); jack_transport_locate(client1, cur_frame / 2); } else if (wait_count == 100) { break; } ts = jack_transport_query(client2, &pos); Log("Locating.... frame = %ld\n", pos.frame); } while (pos.frame > cur_frame); ts = jack_transport_query(client2, &pos); Log("Transport current frame = %ld\n", pos.frame); if (wait_count == 100) { printf("!!! ERROR !!! jack_transport_locate does not work correctly\n"); } // Test jack_transport_reposition while rolling Log("Test jack_transport_reposition while rolling\n"); ts = jack_transport_query(client2, &pos); Log("Transport current frame = %ld\n", pos.frame); cur_frame = pos.frame; wait_count = 0; do { display_transport_state(); jack_sleep(10); // 10 ms // locate at first... wait_count++; if (wait_count == 1) { Log("Do jack_transport_reposition\n"); request_pos.frame = cur_frame / 2; jack_transport_reposition(client1, &request_pos); } else if (wait_count == 100) { break; } ts = jack_transport_query(client2, &pos); Log("Locating.... frame = %ld\n", pos.frame); } while (pos.frame > cur_frame); ts = jack_transport_query(client2, &pos); Log("Transport current frame = %ld\n", pos.frame); if (wait_count == 100) { printf("!!! ERROR !!! jack_transport_reposition does not work correctly\n"); } // Test jack_transport_reposition while stopped jack_transport_stop(client1); ts = jack_transport_query(client2, &pos); Log("Transport current frame = %ld\n", pos.frame); Log("Test jack_transport_reposition while stopped\n"); wait_count = 0; request_pos.frame = 10000; jack_transport_reposition(client1, &request_pos); do { display_transport_state(); jack_sleep(100); // 100 ms if (wait_count++ == 10) break; ts = jack_transport_query(client2, &pos); Log("Locating.... frame = %ld\n", pos.frame); } while (pos.frame != 10000); ts = jack_transport_query(client2, &pos); Log("Transport current frame = %ld\n", pos.frame); if (pos.frame != 10000) { printf("!!! ERROR !!! jack_transport_reposition does not work correctly\n"); } jack_transport_stop(client1); /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ } else { printf("Transport check is disabled...\n"); } time_before_exit = time_to_run; while (time_before_exit != 0) { jack_sleep (1 * 1000); time_before_exit--; } if (jack_deactivate(client2) != 0) { printf("!!! ERROR !!! jack_deactivate does not return 0 for client2 !\n"); } if (jack_deactivate(client1) != 0) { printf("!!! ERROR !!! jack_deactivate does not return 0 for client1 !\n"); } /** * Checking jack_frame_time. */ Log("Testing jack_frame_time...\n"); jack_set_process_callback(client1, process4, client1); jack_activate(client1); jack_sleep(2 * 1000); /** * Checking jack_get_cycle_times. */ Log("Testing jack_get_cycle_times...\n"); jack_deactivate(client1); jack_set_process_callback(client1, process5, client1); jack_activate(client1); jack_sleep(3 * 1000); /** * Checking alternate thread model */ Log("Testing alternate thread model...\n"); jack_deactivate(client1); jack_set_process_callback(client1, NULL, NULL); // remove callback jack_set_process_thread(client1, jack_thread, client1); jack_activate(client1); jack_sleep(2 * 1000); /** * Checking callback exiting : when the return code is != 0, the client is desactivated. */ Log("Testing callback exiting...\n"); jack_deactivate(client1); jack_set_process_thread(client1, NULL, NULL); // remove thread callback jack_set_process_callback(client1, process3, 0); jack_activate(client1); jack_sleep(3 * 1000); /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* Closing program *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* */ if (jack_deactivate(client2) != 0) { printf("!!! ERROR !!! jack_deactivate does not return 0 for client2 !\n"); } if (jack_deactivate(client1) != 0) { printf("!!! ERROR !!! jack_deactivate does not return 0 for client1 !\n"); } if (jack_client_close(client2) != 0) { printf("!!! ERROR !!! jack_client_close does not return 0 for client2 !\n"); } if (jack_client_close(client1) != 0) { printf("!!! ERROR !!! jack_client_close does not return 0 for client1 !\n"); } if (xrun == 0) { Log("No Xrun have been detected during this test... cool !\n"); } else { printf("%i Xrun have been detected during this session (seen callback messages to see where are the problems).\n", xrun); } free(framecollect); free(signal1); free(signal2); Log("Exiting jack_test...\n"); fclose(file); printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); sprintf (filename, "framegraph-%i.gnu", cur_buffer_size); file = fopen(filename, "w"); if (file == NULL) { fprintf(stderr, "Error while opening file"); exit(-1); } fprintf(file, "reset\n"); fprintf(file, "set terminal png transparent nocrop enhanced\n"); fprintf(file, "set output 'framegraph-%i-1.png'\n", cur_buffer_size); fprintf(file, "set title \"Frame time evolution during jack_test run\"\n"); fprintf(file, "set yrange [ %i.00000 : %i.0000 ] noreverse nowriteback\n", cur_buffer_size - (cur_buffer_size / 8), cur_buffer_size + (cur_buffer_size / 8)); fprintf(file, "set xrange [ 0.00000 : %i.0000 ] noreverse nowriteback\n" , linecount - 1); fprintf(file, "set ylabel \"Frametime evolution (d(ft)/dt)\"\n"); fprintf(file, "set xlabel \"FrameTime\"\n"); fprintf(file, "set label \"| buf.siz:%i | fr.wl:%i | rg.ports:%i | 2nd.client:%i | trsprt:%i |\" at graph 0.01, 0.04\n", linebuf, linefw, lineports, linecl2, linetransport); fprintf(file, "plot 'framefile-%i.dat' using 2 with impulses title \"Xruns\",'framefile-%i.dat' using 1 with line title \"Sampletime variation at %i\"\n", cur_buffer_size, cur_buffer_size, cur_buffer_size); fprintf(file, "set output 'framegraph-%i-2.png'\n", cur_buffer_size); fprintf(file, "set title \"Frame time evolution during jack_test run\"\n"); fprintf(file, "set yrange [ %i.00000 : %i.0000 ] noreverse nowriteback\n", (int) (cur_buffer_size / 2), (int) (2*cur_buffer_size + (cur_buffer_size / 8))); fprintf(file, "set xrange [ 0.00000 : %i.0000 ] noreverse nowriteback\n" , linecount - 1); fprintf(file, "set ylabel \"Frametime evolution (d(ft)/dt)\"\n"); fprintf(file, "set xlabel \"FrameTime\"\n"); fprintf(file, "set label \"| buf.siz:%i | fr.wl:%i | rg.ports:%i | 2nd.client:%i | trsprt:%i |\" at graph 0.01, 0.04\n", linebuf, linefw, lineports, linecl2, linetransport); fprintf(file, "plot 'framefile-%i.dat' using 2 with impulses title \"Xruns\",'framefile-%i.dat' using 1 with line title \"Sampletime variation at %i\"\n", cur_buffer_size, cur_buffer_size, cur_buffer_size); fclose(file); return 0; } 1.9.12~dfsg/tests/external_metro.cpp0000644000000000000000000001434413214314510016244 0ustar rootroot/* Copyright (C) 2002 Anthony Van Groningen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "external_metro.h" #include typedef jack_default_audio_sample_t sample_t; const double PI = 3.14; static void JackSleep(int sec) { #ifdef WIN32 Sleep(sec * 1000); #else sleep(sec); #endif } int ExternalMetro::process_audio (jack_nframes_t nframes, void* arg) { ExternalMetro* metro = (ExternalMetro*)arg; sample_t *buffer = (sample_t *) jack_port_get_buffer (metro->output_port, nframes); jack_nframes_t frames_left = nframes; while (metro->wave_length - metro->offset < frames_left) { memcpy (buffer + (nframes - frames_left), metro->wave + metro->offset, sizeof (sample_t) * (metro->wave_length - metro->offset)); frames_left -= metro->wave_length - metro->offset; metro->offset = 0; } if (frames_left > 0) { memcpy (buffer + (nframes - frames_left), metro->wave + metro->offset, sizeof (sample_t) * frames_left); metro->offset += frames_left; } return 0; } void ExternalMetro::shutdown (void* arg) { printf("shutdown called..\n"); } ExternalMetro::ExternalMetro(int freq, double max_amp, int dur_arg, int bpm, const char* client_name) { sample_t scale; int i, attack_length, decay_length; int attack_percent = 1, decay_percent = 10; const char *bpm_string = "bpm"; jack_options_t options = JackNullOption; jack_status_t status; offset = 0; /* Initial Jack setup, get sample rate */ if ((client = jack_client_open (client_name, options, &status)) == 0) { fprintf (stderr, "jack server not running?\n"); throw -1; } jack_set_process_callback (client, process_audio, this); jack_on_shutdown (client, shutdown, this); output_port = jack_port_register (client, bpm_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); input_port = jack_port_register (client, "metro_in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); sr = jack_get_sample_rate (client); /* setup wave table parameters */ wave_length = 60 * sr / bpm; tone_length = sr * dur_arg / 1000; attack_length = tone_length * attack_percent / 100; decay_length = tone_length * decay_percent / 100; scale = 2 * PI * freq / sr; if (tone_length >= wave_length) { /* fprintf (stderr, "invalid duration (tone length = %" PRIu32 ", wave length = %" PRIu32 "\n", tone_length, wave_length); */ return ; } if (attack_length + decay_length > (int)tone_length) { fprintf (stderr, "invalid attack/decay\n"); return ; } /* Build the wave table */ wave = (sample_t *) malloc (wave_length * sizeof(sample_t)); amp = (double *) malloc (tone_length * sizeof(double)); for (i = 0; i < attack_length; i++) { amp[i] = max_amp * i / ((double) attack_length); } for (i = attack_length; i < (int) tone_length - decay_length; i++) { amp[i] = max_amp; } for (i = (int)tone_length - decay_length; i < (int)tone_length; i++) { amp[i] = - max_amp * (i - (double) tone_length) / ((double) decay_length); } for (i = 0; i < (int) tone_length; i++) { wave[i] = amp[i] * sin (scale * i); } for (i = tone_length; i < (int) wave_length; i++) { wave[i] = 0; } if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); } } ExternalMetro::~ExternalMetro() { jack_deactivate(client); jack_port_unregister(client, input_port); jack_port_unregister(client, output_port); jack_client_close(client); free(amp); free(wave); } int main (int argc, char *argv[]) { ExternalMetro* client1 = NULL; ExternalMetro* client2 = NULL; ExternalMetro* client3 = NULL; ExternalMetro* client4 = NULL; ExternalMetro* client5 = NULL; printf("Testing multiple Jack clients in one process: open 5 metro clients...\n"); client1 = new ExternalMetro(1200, 0.4, 20, 80, "t1"); client2 = new ExternalMetro(600, 0.4, 20, 150, "t2"); client3 = new ExternalMetro(1000, 0.4, 20, 110, "t3"); client4 = new ExternalMetro(400, 0.4, 20, 200, "t4"); client5 = new ExternalMetro(1500, 0.4, 20, 150, "t5"); printf("Type 'c' to close all clients and go to next test...\n"); while ((getchar() != 'c')) { JackSleep(1); }; delete client1; delete client2; delete client3; delete client4; delete client5; printf("Testing quitting the server while a client is running...\n"); client1 = new ExternalMetro(1200, 0.4, 20, 80, "t1"); printf("Now quit the server, shutdown callback should be called...\n"); printf("Type 'c' to move on...\n"); while ((getchar() != 'c')) { JackSleep(1); }; printf("Closing client...\n"); delete client1; printf("Now start the server again...\n"); printf("Type 'c' to move on...\n"); while ((getchar() != 'c')) { JackSleep(1); }; printf("Opening a new client....\n"); client1 = new ExternalMetro(1200, 0.4, 20, 80, "t1"); printf("Now quit the server, shutdown callback should be called...\n"); printf("Type 'c' to move on...\n"); while ((getchar() != 'c')) { JackSleep(1); }; printf("Simulating client not correctly closed...\n"); printf("Opening a new client....\n"); try { client1 = new ExternalMetro(1200, 0.4, 20, 80, "t1"); } catch (int num) { printf("Cannot open a new client since old one was not closed correctly... OK\n"); } printf("Type 'q' to quit...\n"); while ((getchar() != 'q')) { JackSleep(1); }; delete client1; return 0; } 1.9.12~dfsg/tests/wscript0000644000000000000000000000212513214314510014120 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 test_programs = { # For testing purposes #'synchroClient': ['testSynchroClient.cpp'], #'synchroServer': ['testSynchroServer.cpp'], #'synchroServerClient': ['testSynchroServerClient.cpp'], #'testSem': ['testSem.cpp'], 'jack_test': ['test.cpp'], 'jack_cpu': ['cpu.c'], 'jack_iodelay': ['iodelay.cpp'], 'jack_multiple_metro' : ['external_metro.cpp'], } def build(bld): for test_program, test_program_sources in list(test_programs.items()): prog = bld(features = 'cxx cxxprogram') if bld.env['IS_MACOSX']: prog.includes = ['..','../macosx', '../posix', '../common/jack', '../common'] if bld.env['IS_LINUX']: prog.includes = ['..','../linux', '../posix', '../common/jack', '../common'] if bld.env['IS_SUN']: prog.includes = ['..','../solaris', '../posix', '../common/jack', '../common'] prog.source = test_program_sources if bld.env['IS_LINUX']: prog.uselib = 'RT' prog.use = 'clientlib' prog.target = test_program 1.9.12~dfsg/tests/testSynchroServer.cpp0000644000000000000000000001221513214314510016723 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef WIN32 #else #include #include #include #include #include #include #include #include #include #include #endif #ifdef __APPLE__ #include "JackMachSemaphore.h" #endif #ifdef WIN32 #include "JackWinEvent.h" #endif #ifdef linux #include "JackPosixSemaphore.h" #include "JackFifo.h" #endif #include "JackPlatformPlug.h" #define ITER 1000 #define SERVER "serveur3" #define CLIENT "client3" using namespace Jack; #ifdef WIN32 LARGE_INTEGER gFreq; long gQueryOverhead; static long elapsed (LARGE_INTEGER* t1, LARGE_INTEGER* t2) { long high = t1->HighPart - t2->HighPart; double low = t1->LowPart - t2->LowPart; // ignore values when high part changes return high ? 0 : (long)((low * 1000000) / gFreq.LowPart); } static BOOL overhead (long * overhead) { LARGE_INTEGER t1, t2; BOOL r1, r2; int i = 50; r1 = QueryPerformanceCounter (&t1); while (i--) QueryPerformanceCounter (&t2); r2 = QueryPerformanceCounter (&t2); if (!r1 || !r2) return FALSE; *overhead = elapsed(&t2, &t1) / 50; return TRUE; } #endif class Test1 : public JackRunnableInterface { private: detail::JackSynchro* fSynchro1; detail::JackSynchro* fSynchro2; public: Test1(detail::JackSynchro* synchro1, detail::JackSynchro* synchro2) : fSynchro1(synchro1), fSynchro2(synchro2) {} bool Execute() { #ifdef WIN32 LARGE_INTEGER t1, t2; BOOL r1, r2; r1 = QueryPerformanceCounter(&t1); #else struct timeval T0, T1; clock_t time1, time2; // Get total time for 2 * ITER process swaps time1 = clock(); gettimeofday(&T0, 0); #endif printf("Execute loop\n"); for (int i = 0; i < ITER; i++) { fSynchro2->Signal(); fSynchro1->Wait(); } #ifdef WIN32 r2 = QueryPerformanceCounter (&t2); elapsed(&t2, &t1); printf ("%5.1lf usec for inter process swap\n", elapsed(&t2, &t1) / (2.0 * ITER)); #else time2 = clock(); gettimeofday(&T1, 0); printf ("%5.1lf usec for inter process swap\n", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec) / (2.0 * ITER)); printf ("%f usec for inter process swap \n", (1e6 * ((time2 - time1) / (double(CLOCKS_PER_SEC)))) / (2.0 * ITER)); #endif return true; } }; int main(int ac, char *av []) { Test1* obj; detail::JackSynchro* sem1 = NULL; detail::JackSynchro* sem2 = NULL; JackThread* thread; #ifdef WIN32 if (!QueryPerformanceFrequency (&gFreq) || !overhead (&gQueryOverhead)) { printf ("cannot query performance counter\n"); } #endif printf("Test of synchronization primitives : server side\n"); printf("type -s to test Posix semaphore\n"); printf("type -f to test Fifo\n"); printf("type -m to test Mach semaphore\n"); printf("type -e to test Windows event\n"); #ifdef __APPLE__ if (strcmp(av[1], "-m") == 0) { printf("Mach semaphore\n"); sem1 = new JackMachSemaphore(); sem2 = new JackMachSemaphore(); } #endif #ifdef WIN32 if (strcmp(av[1], "-e") == 0) { printf("Win event\n"); sem1 = new JackWinEvent(); sem2 = new JackWinEvent(); } #endif #ifdef linux if (strcmp(av[1], "-s") == 0) { printf("Posix semaphore\n"); sem1 = new JackPosixSemaphore(); sem2 = new JackPosixSemaphore(); } if (strcmp(av[1], "-f") == 0) { printf("Fifo\n"); sem1 = new JackFifo(); sem2 = new JackFifo(); } #endif if (!sem1->Allocate(SERVER, "default", 0)) return -1; if (!sem2->Allocate(CLIENT, "default", 0)) return -1; // run test in RT thread obj = new Test1(sem1, sem2); #ifdef __APPLE__ thread = new JackMachThread(obj, 10000 * 1000, 500 * 1000, 10000 * 1000); #endif #ifdef WIN32 thread = new JackWinThread(obj); #endif #ifdef linux thread = new JackPosixThread(obj, false, 50, PTHREAD_CANCEL_DEFERRED); #endif thread->Start(); thread->AcquireRealTime(); #ifdef WIN32 Sleep(90 * 1000); #else sleep(30); #endif thread->Stop(); sem1->Destroy(); sem2->Destroy(); delete obj; delete thread; delete sem1; delete sem2; return 0; } 1.9.12~dfsg/tests/testSynchroClient.cpp0000644000000000000000000000703313214314510016675 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef WIN32 #else #include #include #include #include #include #include #include #include #include #include #endif #ifdef __APPLE__ #include "JackMachSemaphore.h" #endif #ifdef WIN32 #include "JackWinEvent.h" #endif #ifdef linux #include "JackPosixSemaphore.h" #include "JackFifo.h" #endif #include "JackPlatformPlug.h" #define ITER 1000 #define SERVER "serveur3" #define CLIENT "client3" using namespace Jack; class Test2 : public JackRunnableInterface { private: detail::JackSynchro* fSynchro1; detail::JackSynchro* fSynchro2; public: Test2(detail::JackSynchro* synchro1, detail::JackSynchro* synchro2) : fSynchro1(synchro1), fSynchro2(synchro2) {} bool Execute() { int a = 1; for (int i = 0; i < ITER; i++) { fSynchro2->Wait(); for (int j = 0; j < 2000000; j++) { a += j; } fSynchro1->Signal(); } return true; } }; int main(int ac, char *av []) { Test2* obj; detail::JackSynchro* sem1 = NULL; detail::JackSynchro* sem2 = NULL; JackThread* thread; printf("Test of synchronization primitives : client side\n"); printf("type -s to test Posix semaphore\n"); printf("type -f to test Fifo\n"); printf("type -m to test Mach semaphore\n"); printf("type -e to test Windows event\n"); #ifdef __APPLE__ if (strcmp(av[1], "-m") == 0) { printf("Mach semaphore\n"); sem1 = new JackMachSemaphore(); sem2 = new JackMachSemaphore(); } #endif #ifdef WIN32 if (strcmp(av[1], "-e") == 0) { printf("Win event\n"); sem1 = new JackWinEvent(); sem2 = new JackWinEvent(); } #endif #ifdef linux if (strcmp(av[1], "-s") == 0) { printf("Posix semaphore\n"); sem1 = new JackPosixSemaphore(); sem2 = new JackPosixSemaphore(); } if (strcmp(av[1], "-f") == 0) { printf("Fifo\n"); sem1 = new JackFifo(); sem2 = new JackFifo(); } #endif if (!sem1->ConnectOutput(SERVER, "default")) return -1; if (!sem2->ConnectInput(CLIENT, "default")) return -1; obj = new Test2(sem1, sem2); #ifdef __APPLE__ thread = new JackMachThread(obj, 10000 * 1000, 500 * 1000, 10000 * 1000); #endif #ifdef WIN32 thread = new JackWinThread(obj); #endif #ifdef linux thread = new JackPosixThread(obj, false, 50, PTHREAD_CANCEL_DEFERRED); #endif thread->Start(); thread->AcquireRealTime(); #ifdef WIN32 Sleep(30 * 1000); #else sleep(30); #endif //thread->Stop(); thread->Kill(); sem1->Disconnect(); sem2->Disconnect(); delete obj; delete thread; delete sem1; delete sem2; return 0; } 1.9.12~dfsg/tests/testSynchroServerClient.cpp0000644000000000000000000001363413214314510020070 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef WIN32 #else #include #include #include #include #include #include #include #include #include #include #endif #ifdef __APPLE__ #include "JackMachSemaphore.h" #endif #ifdef WIN32 #include "JackWinEvent.h" #endif #ifdef linux #include "JackPosixSemaphore.h" #include "JackFifo.h" #endif #include "JackPlatformPlug.h" #define ITER 100000 #define SERVER "serveur1" #define CLIENT "client1" using namespace Jack; #ifdef WIN32 LARGE_INTEGER gFreq; long gQueryOverhead; static long elapsed (LARGE_INTEGER * t1, LARGE_INTEGER *t2) { long high = t1->HighPart - t2->HighPart; double low = t1->LowPart - t2->LowPart; // ignore values when high part changes return high ? 0 : (long)((low * 1000000) / gFreq.LowPart); } static BOOL overhead (long * overhead) { LARGE_INTEGER t1, t2; BOOL r1, r2; int i = 50; r1 = QueryPerformanceCounter (&t1); while (i--) QueryPerformanceCounter (&t2); r2 = QueryPerformanceCounter (&t2); if (!r1 || !r2) return FALSE; *overhead = elapsed(&t2, &t1) / 50; return TRUE; } #endif template class Test1 : public JackRunnableInterface { private: sync_type* fSynchro1; sync_type* fSynchro2; public: Test1(sync_type* synchro1, sync_type* synchro2) : fSynchro1(synchro1), fSynchro2(synchro2) {} bool Execute() { #ifdef WIN32 LARGE_INTEGER t1, t2; BOOL r1, r2; r1 = QueryPerformanceCounter (&t1); #else struct timeval T0, T1; clock_t time1, time2; // Get total time for 2 * ITER process swaps time1 = clock(); gettimeofday(&T0, 0); #endif printf("Execute loop Test1\n"); for (int i = 0; i < ITER; i++) { fSynchro2->Signal(); fSynchro1->Wait(); } #ifdef WIN32 r2 = QueryPerformanceCounter (&t2); elapsed(&t2, &t1); printf ("%5.1lf usec for inter process swap\n", elapsed(&t2, &t1) / (2.0 * ITER)); #else time2 = clock(); gettimeofday(&T1, 0); printf ("%5.1lf usec for inter process swap\n", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec) / (2.0 * ITER)); printf ("%f usec for inter process swap \n", (1e6 * ((time2 - time1) / (double(CLOCKS_PER_SEC)))) / (2.0 * ITER)); #endif return true; } }; template class Test2 : public JackRunnableInterface { private: sync_type* fSynchro1; sync_type* fSynchro2; public: Test2(sync_type* synchro1, sync_type* synchro2) : fSynchro1(synchro1), fSynchro2(synchro2) {} bool Execute() { printf("Execute loop Test2\n"); for (int i = 0; i < ITER; i++) { fSynchro2->Wait(); fSynchro1->Signal(); } return true; } }; template void run_tests(void) { sync_type sem1, sem2, sem3, sem4; sem1.Allocate(SERVER, "default", 0); sem2.Allocate(CLIENT, "default", 0); sem3.ConnectOutput(SERVER, "default"); sem4.ConnectInput(CLIENT, "default"); Test1 obj1(&sem1, &sem2); Test2 obj2(&sem3, &sem4); JackThread* thread1; JackThread* thread2; #ifdef __APPLE__ thread1 = new JackMachThread(&obj1, 10000 * 1000, 500 * 1000, 10000 * 1000); thread2 = new JackMachThread(&obj2, 10000 * 1000, 500 * 1000, 10000 * 1000); #endif #ifdef WIN32 thread1 = new JackWinThread(&obj1); thread2 = new JackWinThread(&obj2); #endif #ifdef linux thread1 = new JackPosixThread(&obj1, false, 50, PTHREAD_CANCEL_DEFERRED); thread2 = new JackPosixThread(&obj2, false, 50, PTHREAD_CANCEL_DEFERRED); #endif thread1->Start(); thread2->Start(); //thread1->AcquireRealTime(); //thread2->AcquireRealTime(); #ifdef WIN32 Sleep(30 * 1000); #else sleep (30); #endif thread1->Stop(); thread2->Stop(); sem3.Disconnect(); sem4.Disconnect(); sem1.Destroy(); sem2.Destroy(); delete thread1; delete thread2; } int main(int ac, char *av []) { #ifdef WIN32 if (!QueryPerformanceFrequency (&gFreq) || !overhead (&gQueryOverhead)) { printf ("cannot query performance counter\n"); } #endif printf("Test of synchronization primitives : inside a process\n"); printf("type -s to test Posix semaphore\n"); printf("type -f to test Fifo\n"); printf("type -m to test Mach semaphore\n"); printf("type -e to test Windows event\n"); #ifdef __APPLE__ if (strcmp(av[1], "-m") == 0) { printf("Mach semaphore\n"); run_tests(); } #endif #ifdef WIN32 if (strcmp(av[1], "-e") == 0) { printf("Win event\n"); run_tests(); } #endif #ifdef linux if (strcmp(av[1], "-s") == 0) { printf("Posix semaphore\n"); run_tests(); } if (strcmp(av[1], "-f") == 0) { printf("Fifo\n"); run_tests(); } #endif return 0; } 1.9.12~dfsg/tests/testSem.cpp0000644000000000000000000001023413214314510014632 0ustar rootroot/* Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #ifdef __APPLE__ #include "JackMachSemaphore.h" #endif #include "JackPosixSemaphore.h" #include "JackFifo.h" #include "JackPlatformPlug.h" #define ITER 500000 using namespace Jack; struct ServerThread : public JackRunnableInterface { JackThread* fThread; detail::JackSynchro* fServerSem; detail::JackSynchro* fClientSem; ServerThread() { fServerSem->Allocate("JackSemServer", "default", 0); fClientSem->Allocate("JackSemClient", "default", 0); //fThread = new JackMachThread(this); fThread->SetParams(0, 500*1000, 500*1000); fThread->Start(); //fThread->AcquireRealTime(); } virtual ~ServerThread() { fThread->Kill(); delete fThread; } bool Execute() { printf("Execute Server\n"); for (int i = 0; i < ITER; i++) { fClientSem->Signal(); fServerSem->Wait(); } return true; } }; struct ClientThread : public JackRunnableInterface { JackThread* fThread; detail::JackSynchro* fServerSem; detail::JackSynchro* fClientSem; ClientThread() { fServerSem->Connect("JackSemServer", "default"); fClientSem->Connect("JackSemClient", "default"); //fThread = new JackMachThread(this); fThread->SetParams(0, 500*1000, 500*1000); fThread->Start(); //fThread->AcquireRealTime(); } virtual ~ClientThread() { fThread->Kill(); delete fThread; } bool Execute() { struct timeval T0, T1; printf("Execute Client\n"); fClientSem->Wait(); gettimeofday(&T0, 0); for (int i = 0; i < ITER; i++) { fServerSem->Signal(); fClientSem->Wait(); } gettimeofday(&T1, 0); printf("%5.1lf usec\n", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec) / (2.0 * ITER)); return true; } }; void server(detail::JackSynchro* sem) { char c; printf("server\n"); sem->Allocate("JackSem", "default", 0); while (((c = getchar()) != 'q')) { switch(c) { case 's': printf("SynchroSignal....\n"); //sem->Signal(); sem->SignalAll(); printf("SynchroSignal OK\n"); break; case 'w': printf("SemaphoreWait....\n"); sem->Wait(); printf("SemaphoreWait OK\n"); break; } } } void client(detail::JackSynchro* sem) { char c; printf("client\n"); sem->Connect("JackSem", "default"); while (((c = getchar()) != 'q')) { switch(c) { case 's': printf("SemaphoreSignal....\n"); sem->Signal(); printf("SemaphoreSignal OK\n"); break; case 'w': printf("SemaphoreWait....\n"); sem->Wait(); printf("SemaphoreWait OK\n"); break; } } } int main (int argc, char * const argv[]) { char c; ServerThread* serverthread = NULL; ClientThread* clientthread = NULL; detail::JackSynchro* sem1 = NULL; if (strcmp(argv[1],"-s") == 0) { printf("Posix semaphore\n"); sem1 = new JackPosixSemaphore(); } if (strcmp(argv[1],"-f") == 0) { printf("Fifo\n"); sem1 = new JackFifo(); } #ifdef __APPLE__ if (strcmp(argv[1],"-m") == 0) { printf("Mach semaphore\n"); sem1 = new JackMachSemaphore(); } #endif /* if (strcmp(argv[2], "server") == 0) { serverthread = new ServerThread(); } else { clientthread = new ClientThread(); } */ if (strcmp(argv[2], "server") == 0) { server(sem1); } else { client(sem1); } while (((c = getchar()) != 'q')) {} delete serverthread; delete clientthread; } 1.9.12~dfsg/waf0000755000000000000000000001014013214314510012037 0ustar rootroot#!/usr/bin/env python # encoding: ISO8859-1 # Thomas Nagy, 2005-2015 """ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ import os, sys, inspect VERSION="1.8.17" REVISION="x" GIT="x" INSTALL="x" C1='x' C2='x' C3='x' cwd = os.getcwd() join = os.path.join if sys.hexversion<0x206000f: raise ImportError('Python >= 2.6 is required to create the waf file') WAF='waf' def b(x): return x if sys.hexversion>0x300000f: WAF='waf3' def b(x): return x.encode() def err(m): print(('\033[91mError: %s\033[0m' % m)) sys.exit(1) def unpack_wafdir(dir, src): f = open(src,'rb') c = 'corrupt archive (%d)' while 1: line = f.readline() if not line: err('run waf-light from a folder containing waflib') if line == b('#==>\n'): txt = f.readline() if not txt: err(c % 1) if f.readline() != b('#<==\n'): err(c % 2) break if not txt: err(c % 3) txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00')) import shutil, tarfile try: shutil.rmtree(dir) except OSError: pass try: for x in ('Tools', 'extras'): os.makedirs(join(dir, 'waflib', x)) except OSError: err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir) os.chdir(dir) tmp = 't.bz2' t = open(tmp,'wb') try: t.write(txt) finally: t.close() try: t = tarfile.open(tmp) except: try: os.system('bunzip2 t.bz2') t = tarfile.open('t') tmp = 't' except: os.chdir(cwd) try: shutil.rmtree(dir) except OSError: pass err("Waf cannot be unpacked, check that bzip2 support is present") try: for x in t: t.extract(x) finally: t.close() for x in ('Tools', 'extras'): os.chmod(join('waflib',x), 493) if sys.hexversion<0x300000f: sys.path = [join(dir, 'waflib')] + sys.path import fixpy2 fixpy2.fixdir(dir) os.remove(tmp) os.chdir(cwd) try: dir = unicode(dir, 'mbcs') except: pass try: from ctypes import windll windll.kernel32.SetFileAttributesW(dir, 2) except: pass def test(dir): try: os.stat(join(dir, 'waflib')) return os.path.abspath(dir) except OSError: pass def find_lib(): src = os.path.abspath(inspect.getfile(inspect.getmodule(err))) base, name = os.path.split(src) #devs use $WAFDIR w=test(os.environ.get('WAFDIR', '')) if w: return w #waf-light if name.endswith('waf-light'): w = test(base) if w: return w err('waf-light requires waflib -> export WAFDIR=/folder') dirname = '%s-%s-%s' % (WAF, VERSION, REVISION) for i in (INSTALL,'/usr','/usr/local','/opt'): w = test(i + '/lib/' + dirname) if w: return w #waf-local dir = join(base, (sys.platform != 'win32' and '.' or '') + dirname) w = test(dir) if w: return w #unpack unpack_wafdir(dir, src) return dir wafdir = find_lib() sys.path.insert(0, wafdir) if __name__ == '__main__': #import waflib.extras.compat15#PRELUDE from waflib import Scripting Scripting.waf_entry_point(cwd, VERSION, wafdir) 1.9.12~dfsg/TODO0000644000000000000000000000770213214314510012036 0ustar rootroot--------------------- Jackdmp Todo list --------------------- 2008-03-12 : Do not start the client RT thread if no callback or thread routine has been setup (no use of jack_set_process_callback or jack_set_process_thread). This require change in the server to avoid signaling the client in this case. Check direct access from server internal clients (see comment in JackInternalClient::JackInternalClient() in JackInternalClient.cpp) 2008-02-07 : Pipelining idea: - cut the driver buffer size in n slices : clients see the divided value, server deal with the driver value, some clients may want to keep the driver buffer size (non pipelining) - new jack_set_buffer_divisor/jack_get_buffer_divisor and jack_set_pipelining/jack_get_pipelining API - jack_set_buffer_size changes the driver buffer size, jack_get_buffer_size get the divided value - buffer_size callback notify the divided value for pipelining clients 2008-02-06 : Do a "fork-exec" for the server (deamon..) 2008-02-05 : Hierarchical model : having several client graph running simultaneously (Fons) with a "link" between them (AKA NetJack) 2008-01-15 : Server control API (Nedko Arnoudov): would help to develop external control applications (DBUS or OSC based...) 2007-12-16 : Dynamic backend switch, so that audio backend can be switch off and replaced by the dummy backend. 2007-10-17 : Optimize activation call graph with multiple clients in a same process Andrzej Szombierski recently did interesting test to measure jack client activation speed in different context: jack client opened in separated processes, multiple jack clients running in the server, multiple jack clients running in a same separated process, this using jackd or jackdmp. jackd: - multiple jack clients in the server: fast because *direct function call* to the client process callback is done bypassing the fifo based activation system - jack clients in separated processes: slower using the fifo based activation system - multiple jack clients in a separated process: slower using the fifo based activation system jackdmp: - multiple jack clients in the server: slower using the fifo based activation system - jack clients in separated processes: slower using the fifo based activation system - multiple jack clients in a separated process: slower using the fifo based activation system So basically jackdmp use the same fifo based activated system in all cases, and jackd does some optimization in the "multiple jack clients in the server" case. Also having multiple clients in a same process (jack server or separated process) is not so common, it may still be interesting to be able to optimize the activation path with sequential clients in a same process (server or separated). I am thinking in a method that could be done in jackdmp data-flow model : since the activation path is "computed on the fly" when following links between clients, the step where a client activates all its output could be reworked a little with something like : - find one of the client in the output client list that is in the same process - activate all other output clients using the normal fifo based system - *direct* call the client process callback (and this would be done recursively following a sequential path in the graph until no more client in the same process is found) There is still an issue if a client uses the "Fons special" ((-: new jack_thread_wait API, where a client explicitly gives control back to libjack... I still don't have a clear idea if this optimization path could still be done. Even if the "multiple clients" way is not really used in existing applications, is it a desirable feature to have at some point? 2007-10-07 : Before doing an official package, check all public headers 2007-03-14 : Check JackGraphManager::GetPortsAux after MIDI branch merge. 2007-03-14 : Add Paul dynamic jack server location code. 2007-01-22 : Check the "dead" client removing code in the server : non running client may cause Desactivation and Close time out problems. 1.9.12~dfsg/waflib/0000755000000000000000000000000013214314510012604 5ustar rootroot1.9.12~dfsg/waflib/Runner.py0000644000000000000000000002126113214314510014431 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ Runner.py: Task scheduling and execution """ import random, atexit try: from queue import Queue except ImportError: from Queue import Queue from waflib import Utils, Task, Errors, Logs GAP = 10 """ Wait for free tasks if there are at least ``GAP * njobs`` in queue """ class TaskConsumer(Utils.threading.Thread): """ Task consumers belong to a pool of workers They wait for tasks in the queue and then use ``task.process(...)`` """ def __init__(self): Utils.threading.Thread.__init__(self) self.ready = Queue() """ Obtain :py:class:`waflib.Task.TaskBase` instances from this queue. """ self.setDaemon(1) self.start() def run(self): """ Loop over the tasks to execute """ try: self.loop() except Exception: pass def loop(self): """ Obtain tasks from :py:attr:`waflib.Runner.TaskConsumer.ready` and call :py:meth:`waflib.Task.TaskBase.process`. If the object is a function, execute it. """ while 1: tsk = self.ready.get() if not isinstance(tsk, Task.TaskBase): tsk(self) else: tsk.process() pool = Queue() """ Pool of task consumer objects """ def get_pool(): """ Obtain a task consumer from :py:attr:`waflib.Runner.pool`. Do not forget to put it back by using :py:func:`waflib.Runner.put_pool` and reset properly (original waiting queue). :rtype: :py:class:`waflib.Runner.TaskConsumer` """ try: return pool.get(False) except Exception: return TaskConsumer() def put_pool(x): """ Return a task consumer to the thread pool :py:attr:`waflib.Runner.pool` :param x: task consumer object :type x: :py:class:`waflib.Runner.TaskConsumer` """ pool.put(x) def _free_resources(): global pool lst = [] while pool.qsize(): lst.append(pool.get()) for x in lst: x.ready.put(None) for x in lst: x.join() pool = None atexit.register(_free_resources) class Parallel(object): """ Schedule the tasks obtained from the build context for execution. """ def __init__(self, bld, j=2): """ The initialization requires a build context reference for computing the total number of jobs. """ self.numjobs = j """ Number of consumers in the pool """ self.bld = bld """ Instance of :py:class:`waflib.Build.BuildContext` """ self.outstanding = [] """List of :py:class:`waflib.Task.TaskBase` that may be ready to be executed""" self.frozen = [] """List of :py:class:`waflib.Task.TaskBase` that cannot be executed immediately""" self.out = Queue(0) """List of :py:class:`waflib.Task.TaskBase` returned by the task consumers""" self.count = 0 """Amount of tasks that may be processed by :py:class:`waflib.Runner.TaskConsumer`""" self.processed = 1 """Amount of tasks processed""" self.stop = False """Error flag to stop the build""" self.error = [] """Tasks that could not be executed""" self.biter = None """Task iterator which must give groups of parallelizable tasks when calling ``next()``""" self.dirty = False """Flag to indicate that tasks have been executed, and that the build cache must be saved (call :py:meth:`waflib.Build.BuildContext.store`)""" def get_next_task(self): """ Obtain the next task to execute. :rtype: :py:class:`waflib.Task.TaskBase` """ if not self.outstanding: return None return self.outstanding.pop(0) def postpone(self, tsk): """ A task cannot be executed at this point, put it in the list :py:attr:`waflib.Runner.Parallel.frozen`. :param tsk: task :type tsk: :py:class:`waflib.Task.TaskBase` """ if random.randint(0, 1): self.frozen.insert(0, tsk) else: self.frozen.append(tsk) def refill_task_list(self): """ Put the next group of tasks to execute in :py:attr:`waflib.Runner.Parallel.outstanding`. """ while self.count > self.numjobs * GAP: self.get_out() while not self.outstanding: if self.count: self.get_out() elif self.frozen: try: cond = self.deadlock == self.processed except AttributeError: pass else: if cond: msg = 'check the build order for the tasks' for tsk in self.frozen: if not tsk.run_after: msg = 'check the methods runnable_status' break lst = [] for tsk in self.frozen: lst.append('%s\t-> %r' % (repr(tsk), [id(x) for x in tsk.run_after])) raise Errors.WafError('Deadlock detected: %s%s' % (msg, ''.join(lst))) self.deadlock = self.processed if self.frozen: self.outstanding += self.frozen self.frozen = [] elif not self.count: self.outstanding.extend(next(self.biter)) self.total = self.bld.total() break def add_more_tasks(self, tsk): """ Tasks may be added dynamically during the build by binding them to the task :py:attr:`waflib.Task.TaskBase.more_tasks` :param tsk: task :type tsk: :py:attr:`waflib.Task.TaskBase` """ if getattr(tsk, 'more_tasks', None): self.outstanding += tsk.more_tasks self.total += len(tsk.more_tasks) def get_out(self): """ Obtain one task returned from the task consumers, and update the task count. Add more tasks if necessary through :py:attr:`waflib.Runner.Parallel.add_more_tasks`. :rtype: :py:attr:`waflib.Task.TaskBase` """ tsk = self.out.get() if not self.stop: self.add_more_tasks(tsk) self.count -= 1 self.dirty = True return tsk def add_task(self, tsk): """ Pass a task to a consumer. :param tsk: task :type tsk: :py:attr:`waflib.Task.TaskBase` """ try: self.pool except AttributeError: self.init_task_pool() self.ready.put(tsk) def init_task_pool(self): # lazy creation, and set a common pool for all task consumers pool = self.pool = [get_pool() for i in range(self.numjobs)] self.ready = Queue(0) def setq(consumer): consumer.ready = self.ready for x in pool: x.ready.put(setq) return pool def free_task_pool(self): # return the consumers, setting a different queue for each of them def setq(consumer): consumer.ready = Queue(0) self.out.put(self) try: pool = self.pool except AttributeError: pass else: for x in pool: self.ready.put(setq) for x in pool: self.get_out() for x in pool: put_pool(x) self.pool = [] def skip(self, tsk): tsk.hasrun = Task.SKIPPED def error_handler(self, tsk): """ Called when a task cannot be executed. The flag :py:attr:`waflib.Runner.Parallel.stop` is set, unless the build is executed with:: $ waf build -k :param tsk: task :type tsk: :py:attr:`waflib.Task.TaskBase` """ if hasattr(tsk, 'scan') and hasattr(tsk, 'uid'): # TODO waf 1.9 - this breaks encapsulation key = (tsk.uid(), 'imp') try: del self.bld.task_sigs[key] except KeyError: pass if not self.bld.keep: self.stop = True self.error.append(tsk) def task_status(self, tsk): try: return tsk.runnable_status() except Exception: self.processed += 1 tsk.err_msg = Utils.ex_stack() if not self.stop and self.bld.keep: self.skip(tsk) if self.bld.keep == 1: # if -k stop at the first exception, if -kk try to go as far as possible if Logs.verbose > 1 or not self.error: self.error.append(tsk) self.stop = True else: if Logs.verbose > 1: self.error.append(tsk) return Task.EXCEPTION tsk.hasrun = Task.EXCEPTION self.error_handler(tsk) return Task.EXCEPTION def start(self): """ Give tasks to :py:class:`waflib.Runner.TaskConsumer` instances until the build finishes or the ``stop`` flag is set. If only one job is used, then execute the tasks one by one, without consumers. """ self.total = self.bld.total() while not self.stop: self.refill_task_list() # consider the next task tsk = self.get_next_task() if not tsk: if self.count: # tasks may add new ones after they are run continue else: # no tasks to run, no tasks running, time to exit break if tsk.hasrun: # if the task is marked as "run", just skip it self.processed += 1 continue if self.stop: # stop immediately after a failure was detected break st = self.task_status(tsk) if st == Task.RUN_ME: tsk.position = (self.processed, self.total) self.count += 1 tsk.master = self self.processed += 1 if self.numjobs == 1: tsk.process() else: self.add_task(tsk) if st == Task.ASK_LATER: self.postpone(tsk) elif st == Task.SKIP_ME: self.processed += 1 self.skip(tsk) self.add_more_tasks(tsk) # self.count represents the tasks that have been made available to the consumer threads # collect all the tasks after an error else the message may be incomplete while self.error and self.count: self.get_out() #print loop assert (self.count == 0 or self.stop) # free the task pool, if any self.free_task_pool() 1.9.12~dfsg/waflib/Scripting.py0000644000000000000000000004064213214314510015126 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) "Module called for configuring, compiling and installing targets" import os, shlex, shutil, traceback, errno, sys, stat from waflib import Utils, Configure, Logs, Options, ConfigSet, Context, Errors, Build, Node build_dir_override = None no_climb_commands = ['configure'] default_cmd = "build" def waf_entry_point(current_directory, version, wafdir): """ This is the main entry point, all Waf execution starts here. :param current_directory: absolute path representing the current directory :type current_directory: string :param version: version number :type version: string :param wafdir: absolute path representing the directory of the waf library :type wafdir: string """ Logs.init_log() if Context.WAFVERSION != version: Logs.error('Waf script %r and library %r do not match (directory %r)' % (version, Context.WAFVERSION, wafdir)) sys.exit(1) if '--version' in sys.argv: Context.run_dir = current_directory ctx = Context.create_context('options') ctx.curdir = current_directory ctx.parse_args() sys.exit(0) if len(sys.argv) > 1: # os.path.join handles absolute paths in sys.argv[1] accordingly (it discards the previous ones) # if sys.argv[1] is not an absolute path, then it is relative to the current working directory potential_wscript = os.path.join(current_directory, sys.argv[1]) # maybe check if the file is executable # perhaps extract 'wscript' as a constant if os.path.basename(potential_wscript) == 'wscript' and os.path.isfile(potential_wscript): # need to explicitly normalize the path, as it may contain extra '/.' # TODO abspath? current_directory = os.path.normpath(os.path.dirname(potential_wscript)) sys.argv.pop(1) Context.waf_dir = wafdir Context.launch_dir = current_directory # if 'configure' is in the commands, do not search any further no_climb = os.environ.get('NOCLIMB', None) if not no_climb: for k in no_climb_commands: for y in sys.argv: if y.startswith(k): no_climb = True break # if --top is provided assume the build started in the top directory for i, x in enumerate(sys.argv): # WARNING: this modifies sys.argv if x.startswith('--top='): Context.run_dir = Context.top_dir = Utils.sane_path(x[6:]) sys.argv[i] = '--top=' + Context.run_dir if x.startswith('--out='): Context.out_dir = Utils.sane_path(x[6:]) sys.argv[i] = '--out=' + Context.out_dir # try to find a lock file (if the project was configured) # at the same time, store the first wscript file seen cur = current_directory while cur and not Context.top_dir: lst = os.listdir(cur) if Options.lockfile in lst: env = ConfigSet.ConfigSet() try: env.load(os.path.join(cur, Options.lockfile)) ino = os.stat(cur)[stat.ST_INO] except Exception: pass else: # check if the folder was not moved for x in (env.run_dir, env.top_dir, env.out_dir): if Utils.is_win32: if cur == x: load = True break else: # if the filesystem features symlinks, compare the inode numbers try: ino2 = os.stat(x)[stat.ST_INO] except OSError: pass else: if ino == ino2: load = True break else: Logs.warn('invalid lock file in %s' % cur) load = False if load: Context.run_dir = env.run_dir Context.top_dir = env.top_dir Context.out_dir = env.out_dir break if not Context.run_dir: if Context.WSCRIPT_FILE in lst: Context.run_dir = cur next = os.path.dirname(cur) if next == cur: break cur = next if no_climb: break if not Context.run_dir: if '-h' in sys.argv or '--help' in sys.argv: Logs.warn('No wscript file found: the help message may be incomplete') Context.run_dir = current_directory ctx = Context.create_context('options') ctx.curdir = current_directory ctx.parse_args() sys.exit(0) Logs.error('Waf: Run from a directory containing a file named %r' % Context.WSCRIPT_FILE) sys.exit(1) try: os.chdir(Context.run_dir) except OSError: Logs.error('Waf: The folder %r is unreadable' % Context.run_dir) sys.exit(1) try: set_main_module(os.path.normpath(os.path.join(Context.run_dir, Context.WSCRIPT_FILE))) except Errors.WafError as e: Logs.pprint('RED', e.verbose_msg) Logs.error(str(e)) sys.exit(1) except Exception as e: Logs.error('Waf: The wscript in %r is unreadable' % Context.run_dir, e) traceback.print_exc(file=sys.stdout) sys.exit(2) """ import cProfile, pstats cProfile.runctx("from waflib import Scripting; Scripting.run_commands()", {}, {}, 'profi.txt') p = pstats.Stats('profi.txt') p.sort_stats('time').print_stats(75) # or 'cumulative' """ try: run_commands() except Errors.WafError as e: if Logs.verbose > 1: Logs.pprint('RED', e.verbose_msg) Logs.error(e.msg) sys.exit(1) except SystemExit: raise except Exception as e: traceback.print_exc(file=sys.stdout) sys.exit(2) except KeyboardInterrupt: Logs.pprint('RED', 'Interrupted') sys.exit(68) #""" def set_main_module(file_path): """ Read the main wscript file into :py:const:`waflib.Context.Context.g_module` and bind default functions such as ``init``, ``dist``, ``distclean`` if not defined. Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. :param file_path: absolute path representing the top-level wscript file :type file_path: string """ Context.g_module = Context.load_module(file_path) Context.g_module.root_path = file_path # note: to register the module globally, use the following: # sys.modules['wscript_main'] = g_module def set_def(obj): name = obj.__name__ if not name in Context.g_module.__dict__: setattr(Context.g_module, name, obj) for k in (update, dist, distclean, distcheck, update): set_def(k) # add dummy init and shutdown functions if they're not defined if not 'init' in Context.g_module.__dict__: Context.g_module.init = Utils.nada if not 'shutdown' in Context.g_module.__dict__: Context.g_module.shutdown = Utils.nada if not 'options' in Context.g_module.__dict__: Context.g_module.options = Utils.nada def parse_options(): """ Parse the command-line options and initialize the logging system. Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. """ Context.create_context('options').execute() for var in Options.envvars: (name, value) = var.split('=', 1) os.environ[name.strip()] = value if not Options.commands: Options.commands = [default_cmd] Options.commands = [x for x in Options.commands if x != 'options'] # issue 1076 # process some internal Waf options Logs.verbose = Options.options.verbose #Logs.init_log() if Options.options.zones: Logs.zones = Options.options.zones.split(',') if not Logs.verbose: Logs.verbose = 1 elif Logs.verbose > 0: Logs.zones = ['runner'] if Logs.verbose > 2: Logs.zones = ['*'] def run_command(cmd_name): """ Execute a single command. Called by :py:func:`waflib.Scripting.run_commands`. :param cmd_name: command to execute, like ``build`` :type cmd_name: string """ ctx = Context.create_context(cmd_name) ctx.log_timer = Utils.Timer() ctx.options = Options.options # provided for convenience ctx.cmd = cmd_name try: ctx.execute() finally: # Issue 1374 ctx.finalize() return ctx def run_commands(): """ Execute the commands that were given on the command-line, and the other options Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization, and executed after :py:func:`waflib.Scripting.parse_options`. """ parse_options() run_command('init') while Options.commands: cmd_name = Options.commands.pop(0) ctx = run_command(cmd_name) Logs.info('%r finished successfully (%s)' % (cmd_name, str(ctx.log_timer))) run_command('shutdown') ########################################################################################### def _can_distclean(name): # WARNING: this method may disappear anytime for k in '.o .moc .exe'.split(): if name.endswith(k): return True return False def distclean_dir(dirname): """ Distclean function called in the particular case when:: top == out :param dirname: absolute path of the folder to clean :type dirname: string """ for (root, dirs, files) in os.walk(dirname): for f in files: if _can_distclean(f): fname = os.path.join(root, f) try: os.remove(fname) except OSError: Logs.warn('Could not remove %r' % fname) for x in (Context.DBFILE, 'config.log'): try: os.remove(x) except OSError: pass try: shutil.rmtree('c4che') except OSError: pass def distclean(ctx): '''removes the build directory''' lst = os.listdir('.') for f in lst: if f == Options.lockfile: try: proj = ConfigSet.ConfigSet(f) except IOError: Logs.warn('Could not read %r' % f) continue if proj['out_dir'] != proj['top_dir']: try: shutil.rmtree(proj['out_dir']) except IOError: pass except OSError as e: if e.errno != errno.ENOENT: Logs.warn('Could not remove %r' % proj['out_dir']) else: distclean_dir(proj['out_dir']) for k in (proj['out_dir'], proj['top_dir'], proj['run_dir']): p = os.path.join(k, Options.lockfile) try: os.remove(p) except OSError as e: if e.errno != errno.ENOENT: Logs.warn('Could not remove %r' % p) # remove local waf cache folders if not Options.commands: for x in '.waf-1. waf-1. .waf3-1. waf3-1.'.split(): if f.startswith(x): shutil.rmtree(f, ignore_errors=True) class Dist(Context.Context): '''creates an archive containing the project source code''' cmd = 'dist' fun = 'dist' algo = 'tar.bz2' ext_algo = {} def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ self.recurse([os.path.dirname(Context.g_module.root_path)]) self.archive() def archive(self): """ Create the archive. """ import tarfile arch_name = self.get_arch_name() try: self.base_path except AttributeError: self.base_path = self.path node = self.base_path.make_node(arch_name) try: node.delete() except OSError: pass files = self.get_files() if self.algo.startswith('tar.'): tar = tarfile.open(arch_name, 'w:' + self.algo.replace('tar.', '')) for x in files: self.add_tar_file(x, tar) tar.close() elif self.algo == 'zip': import zipfile zip = zipfile.ZipFile(arch_name, 'w', compression=zipfile.ZIP_DEFLATED) for x in files: archive_name = self.get_base_name() + '/' + x.path_from(self.base_path) zip.write(x.abspath(), archive_name, zipfile.ZIP_DEFLATED) zip.close() else: self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip') try: from hashlib import sha1 as sha except ImportError: from sha import sha try: digest = " (sha=%r)" % sha(node.read()).hexdigest() except Exception: digest = '' Logs.info('New archive created: %s%s' % (self.arch_name, digest)) def get_tar_path(self, node): """ return the path to use for a node in the tar archive, the purpose of this is to let subclases resolve symbolic links or to change file names """ return node.abspath() def add_tar_file(self, x, tar): """ Add a file to the tar archive. Transform symlinks into files if the files lie out of the project tree. """ p = self.get_tar_path(x) tinfo = tar.gettarinfo(name=p, arcname=self.get_tar_prefix() + '/' + x.path_from(self.base_path)) tinfo.uid = 0 tinfo.gid = 0 tinfo.uname = 'root' tinfo.gname = 'root' fu = None try: fu = open(p, 'rb') tar.addfile(tinfo, fileobj=fu) finally: if fu: fu.close() def get_tar_prefix(self): try: return self.tar_prefix except AttributeError: return self.get_base_name() def get_arch_name(self): """ Return the name of the archive to create. Change the default value by setting *arch_name*:: def dist(ctx): ctx.arch_name = 'ctx.tar.bz2' :rtype: string """ try: self.arch_name except AttributeError: self.arch_name = self.get_base_name() + '.' + self.ext_algo.get(self.algo, self.algo) return self.arch_name def get_base_name(self): """ Return the default name of the main directory in the archive, which is set to *appname-version*. Set the attribute *base_name* to change the default value:: def dist(ctx): ctx.base_name = 'files' :rtype: string """ try: self.base_name except AttributeError: appname = getattr(Context.g_module, Context.APPNAME, 'noname') version = getattr(Context.g_module, Context.VERSION, '1.0') self.base_name = appname + '-' + version return self.base_name def get_excl(self): """ Return the patterns to exclude for finding the files in the top-level directory. Set the attribute *excl* to change the default value:: def dist(ctx): ctx.excl = 'build **/*.o **/*.class' :rtype: string """ try: return self.excl except AttributeError: self.excl = Node.exclude_regs + ' **/waf-1.8.* **/.waf-1.8* **/waf3-1.8.* **/.waf3-1.8* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' if Context.out_dir: nd = self.root.find_node(Context.out_dir) if nd: self.excl += ' ' + nd.path_from(self.base_path) return self.excl def get_files(self): """ The files to package are searched automatically by :py:func:`waflib.Node.Node.ant_glob`. Set *files* to prevent this behaviour:: def dist(ctx): ctx.files = ctx.path.find_node('wscript') The files are searched from the directory 'base_path', to change it, set:: def dist(ctx): ctx.base_path = path :rtype: list of :py:class:`waflib.Node.Node` """ try: files = self.files except AttributeError: files = self.base_path.ant_glob('**/*', excl=self.get_excl()) return files def dist(ctx): '''makes a tarball for redistributing the sources''' pass class DistCheck(Dist): """ Create an archive of the project, and try to build the project in a temporary directory:: $ waf distcheck """ fun = 'distcheck' cmd = 'distcheck' def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ self.recurse([os.path.dirname(Context.g_module.root_path)]) self.archive() self.check() def check(self): """ Create the archive, uncompress it and try to build the project """ import tempfile, tarfile t = None try: t = tarfile.open(self.get_arch_name()) for x in t: t.extract(x) finally: if t: t.close() cfg = [] if Options.options.distcheck_args: cfg = shlex.split(Options.options.distcheck_args) else: cfg = [x for x in sys.argv if x.startswith('-')] instdir = tempfile.mkdtemp('.inst', self.get_base_name()) ret = Utils.subprocess.Popen([sys.executable, sys.argv[0], 'configure', 'install', 'uninstall', '--destdir=' + instdir] + cfg, cwd=self.get_base_name()).wait() if ret: raise Errors.WafError('distcheck failed with code %i' % ret) if os.path.exists(instdir): raise Errors.WafError('distcheck succeeded, but files were left in %s' % instdir) shutil.rmtree(self.get_base_name()) def distcheck(ctx): '''checks if the project compiles (tarball from 'dist')''' pass def update(ctx): lst = Options.options.files if lst: lst = lst.split(',') else: path = os.path.join(Context.waf_dir, 'waflib', 'extras') lst = [x for x in Utils.listdir(path) if x.endswith('.py')] for x in lst: tool = x.replace('.py', '') if not tool: continue try: dl = Configure.download_tool except AttributeError: ctx.fatal('The command "update" is dangerous; include the tool "use_config" in your project!') try: dl(tool, force=True, ctx=ctx) except Errors.WafError: Logs.error('Could not find the tool %r in the remote repository' % x) else: Logs.warn('Updated %r' % tool) def autoconfigure(execute_method): """ Decorator used to set the commands that can be configured automatically """ def execute(self): if not Configure.autoconfig: return execute_method(self) env = ConfigSet.ConfigSet() do_config = False try: env.load(os.path.join(Context.top_dir, Options.lockfile)) except Exception: Logs.warn('Configuring the project') do_config = True else: if env.run_dir != Context.run_dir: do_config = True else: h = 0 for f in env['files']: h = Utils.h_list((h, Utils.readf(f, 'rb'))) do_config = h != env.hash if do_config: Options.commands.insert(0, self.cmd) Options.commands.insert(0, 'configure') if Configure.autoconfig == 'clobber': Options.options.__dict__ = env.options return return execute_method(self) return execute Build.BuildContext.execute = autoconfigure(Build.BuildContext.execute) 1.9.12~dfsg/waflib/Logs.py0000644000000000000000000002042113214314510014061 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ logging, colors, terminal width and pretty-print """ import os, re, traceback, sys from waflib import Utils, ansiterm if not os.environ.get('NOSYNC', False): # synchronized output is nearly mandatory to prevent garbled output if sys.stdout.isatty() and id(sys.stdout) == id(sys.__stdout__): sys.stdout = ansiterm.AnsiTerm(sys.stdout) if sys.stderr.isatty() and id(sys.stderr) == id(sys.__stderr__): sys.stderr = ansiterm.AnsiTerm(sys.stderr) # import the logging module after since it holds a reference on sys.stderr # in case someone uses the root logger import logging LOG_FORMAT = os.environ.get('WAF_LOG_FORMAT', '%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s') HOUR_FORMAT = os.environ.get('WAF_HOUR_FORMAT', '%H:%M:%S') zones = '' verbose = 0 colors_lst = { 'USE' : True, 'BOLD' :'\x1b[01;1m', 'RED' :'\x1b[01;31m', 'GREEN' :'\x1b[32m', 'YELLOW':'\x1b[33m', 'PINK' :'\x1b[35m', 'BLUE' :'\x1b[01;34m', 'CYAN' :'\x1b[36m', 'GREY' :'\x1b[37m', 'NORMAL':'\x1b[0m', 'cursor_on' :'\x1b[?25h', 'cursor_off' :'\x1b[?25l', } indicator = '\r\x1b[K%s%s%s' try: unicode except NameError: unicode = None def enable_colors(use): if use == 1: if not (sys.stderr.isatty() or sys.stdout.isatty()): use = 0 if Utils.is_win32 and os.name != 'java': term = os.environ.get('TERM', '') # has ansiterm else: term = os.environ.get('TERM', 'dumb') if term in ('dumb', 'emacs'): use = 0 if use >= 1: os.environ['TERM'] = 'vt100' colors_lst['USE'] = use # If console packages are available, replace the dummy function with a real # implementation try: get_term_cols = ansiterm.get_term_cols except AttributeError: def get_term_cols(): return 80 get_term_cols.__doc__ = """ Get the console width in characters. :return: the number of characters per line :rtype: int """ def get_color(cl): if not colors_lst['USE']: return '' return colors_lst.get(cl, '') class color_dict(object): """attribute-based color access, eg: colors.PINK""" def __getattr__(self, a): return get_color(a) def __call__(self, a): return get_color(a) colors = color_dict() re_log = re.compile(r'(\w+): (.*)', re.M) class log_filter(logging.Filter): """ The waf logs are of the form 'name: message', and can be filtered by 'waf --zones=name'. For example, the following:: from waflib import Logs Logs.debug('test: here is a message') Will be displayed only when executing:: $ waf --zones=test """ def __init__(self, name=None): pass def filter(self, rec): """ filter a record, adding the colors automatically * error: red * warning: yellow :param rec: message to record """ rec.zone = rec.module if rec.levelno >= logging.INFO: return True m = re_log.match(rec.msg) if m: rec.zone = m.group(1) rec.msg = m.group(2) if zones: return getattr(rec, 'zone', '') in zones or '*' in zones elif not verbose > 2: return False return True class log_handler(logging.StreamHandler): """Dispatches messages to stderr/stdout depending on the severity level""" def emit(self, record): # default implementation try: try: self.stream = record.stream except AttributeError: if record.levelno >= logging.WARNING: record.stream = self.stream = sys.stderr else: record.stream = self.stream = sys.stdout self.emit_override(record) self.flush() except (KeyboardInterrupt, SystemExit): raise except: # from the python library -_- self.handleError(record) def emit_override(self, record, **kw): self.terminator = getattr(record, 'terminator', '\n') stream = self.stream if unicode: # python2 msg = self.formatter.format(record) fs = '%s' + self.terminator try: if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): fs = fs.decode(stream.encoding) try: stream.write(fs % msg) except UnicodeEncodeError: stream.write((fs % msg).encode(stream.encoding)) else: stream.write(fs % msg) except UnicodeError: stream.write((fs % msg).encode("UTF-8")) else: logging.StreamHandler.emit(self, record) class formatter(logging.Formatter): """Simple log formatter which handles colors""" def __init__(self): logging.Formatter.__init__(self, LOG_FORMAT, HOUR_FORMAT) def format(self, rec): """Messages in warning, error or info mode are displayed in color by default""" try: msg = rec.msg.decode('utf-8') except Exception: msg = rec.msg use = colors_lst['USE'] if (use == 1 and rec.stream.isatty()) or use == 2: c1 = getattr(rec, 'c1', None) if c1 is None: c1 = '' if rec.levelno >= logging.ERROR: c1 = colors.RED elif rec.levelno >= logging.WARNING: c1 = colors.YELLOW elif rec.levelno >= logging.INFO: c1 = colors.GREEN c2 = getattr(rec, 'c2', colors.NORMAL) msg = '%s%s%s' % (c1, msg, c2) else: msg = msg.replace('\r', '\n') msg = re.sub(r'\x1B\[(K|.*?(m|h|l))', '', msg) if rec.levelno >= logging.INFO: # ?? return msg rec.msg = msg rec.c1 = colors.PINK rec.c2 = colors.NORMAL return logging.Formatter.format(self, rec) log = None """global logger for Logs.debug, Logs.error, etc""" def debug(*k, **kw): """ Wrap logging.debug, the output is filtered for performance reasons """ if verbose: k = list(k) k[0] = k[0].replace('\n', ' ') global log log.debug(*k, **kw) def error(*k, **kw): """ Wrap logging.errors, display the origin of the message when '-vv' is set """ global log log.error(*k, **kw) if verbose > 2: st = traceback.extract_stack() if st: st = st[:-1] buf = [] for filename, lineno, name, line in st: buf.append(' File "%s", line %d, in %s' % (filename, lineno, name)) if line: buf.append(' %s' % line.strip()) if buf: log.error("\n".join(buf)) def warn(*k, **kw): """ Wrap logging.warn """ global log log.warn(*k, **kw) def info(*k, **kw): """ Wrap logging.info """ global log log.info(*k, **kw) def init_log(): """ Initialize the loggers globally """ global log log = logging.getLogger('waflib') log.handlers = [] log.filters = [] hdlr = log_handler() hdlr.setFormatter(formatter()) log.addHandler(hdlr) log.addFilter(log_filter()) log.setLevel(logging.DEBUG) def make_logger(path, name): """ Create a simple logger, which is often used to redirect the context command output:: from waflib import Logs bld.logger = Logs.make_logger('test.log', 'build') bld.check(header_name='sadlib.h', features='cxx cprogram', mandatory=False) # have the file closed immediately Logs.free_logger(bld.logger) # stop logging bld.logger = None The method finalize() of the command will try to free the logger, if any :param path: file name to write the log output to :type path: string :param name: logger name (loggers are reused) :type name: string """ logger = logging.getLogger(name) hdlr = logging.FileHandler(path, 'w') formatter = logging.Formatter('%(message)s') hdlr.setFormatter(formatter) logger.addHandler(hdlr) logger.setLevel(logging.DEBUG) return logger def make_mem_logger(name, to_log, size=8192): """ Create a memory logger to avoid writing concurrently to the main logger """ from logging.handlers import MemoryHandler logger = logging.getLogger(name) hdlr = MemoryHandler(size, target=to_log) formatter = logging.Formatter('%(message)s') hdlr.setFormatter(formatter) logger.addHandler(hdlr) logger.memhandler = hdlr logger.setLevel(logging.DEBUG) return logger def free_logger(logger): """ Free the resources held by the loggers created through make_logger or make_mem_logger. This is used for file cleanup and for handler removal (logger objects are re-used). """ try: for x in logger.handlers: x.close() logger.removeHandler(x) except Exception: pass def pprint(col, msg, label='', sep='\n'): """ Print messages in color immediately on stderr:: from waflib import Logs Logs.pprint('RED', 'Something bad just happened') :param col: color name to use in :py:const:`Logs.colors_lst` :type col: string :param msg: message to display :type msg: string or a value that can be printed by %s :param label: a message to add after the colored output :type label: string :param sep: a string to append at the end (line separator) :type sep: string """ info("%s%s%s %s" % (colors(col), msg, colors.NORMAL, label), extra={'terminator':sep}) 1.9.12~dfsg/waflib/fixpy2.py0000644000000000000000000000253613214314510014405 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010-2015 (ita) """ burn a book, save a tree """ import os all_modifs = {} def fixdir(dir): """call all the substitution functions on the waf folders""" global all_modifs for k in all_modifs: for v in all_modifs[k]: modif(os.path.join(dir, 'waflib'), k, v) def modif(dir, name, fun): """execute a substitution function""" if name == '*': lst = [] for y in '. Tools extras'.split(): for x in os.listdir(os.path.join(dir, y)): if x.endswith('.py'): lst.append(y + os.sep + x) for x in lst: modif(dir, x, fun) return filename = os.path.join(dir, name) f = open(filename, 'r') try: txt = f.read() finally: f.close() txt = fun(txt) f = open(filename, 'w') try: f.write(txt) finally: f.close() def subst(*k): """register a substitution function""" def do_subst(fun): global all_modifs for x in k: try: all_modifs[x].append(fun) except KeyError: all_modifs[x] = [fun] return fun return do_subst @subst('*') def r1(code): "utf-8 fixes for python < 2.6" code = code.replace('as e:', ',e:') code = code.replace(".decode(sys.stdout.encoding or 'iso8859-1')", '') code = code.replace('.encode()', '') return code @subst('Runner.py') def r4(code): "generator syntax" code = code.replace('next(self.biter)', 'self.biter.next()') return code 1.9.12~dfsg/waflib/Node.py0000644000000000000000000005060013214314510014044 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ Node: filesystem structure, contains lists of nodes #. Each file/folder is represented by exactly one node. #. Some potential class properties are stored on :py:class:`waflib.Build.BuildContext` : nodes to depend on, etc. Unused class members can increase the `.wafpickle` file size sensibly. #. Node objects should never be created directly, use the methods :py:func:`Node.make_node` or :py:func:`Node.find_node` #. The methods :py:func:`Node.find_resource`, :py:func:`Node.find_dir` :py:func:`Node.find_or_declare` should be used when a build context is present #. Each instance of :py:class:`waflib.Context.Context` has a unique :py:class:`Node` subclass. (:py:class:`waflib.Node.Nod3`, see the :py:class:`waflib.Context.Context` initializer). A reference to the context owning a node is held as self.ctx """ import os, re, sys, shutil from waflib import Utils, Errors exclude_regs = ''' **/*~ **/#*# **/.#* **/%*% **/._* **/CVS **/CVS/** **/.cvsignore **/SCCS **/SCCS/** **/vssver.scc **/.svn **/.svn/** **/BitKeeper **/.git **/.git/** **/.gitignore **/.bzr **/.bzrignore **/.bzr/** **/.hg **/.hg/** **/_MTN **/_MTN/** **/.arch-ids **/{arch} **/_darcs **/_darcs/** **/.intlcache **/.DS_Store''' """ Ant patterns for files and folders to exclude while doing the recursive traversal in :py:meth:`waflib.Node.Node.ant_glob` """ # TODO remove in waf 1.9 split_path = Utils.split_path split_path_unix = Utils.split_path_unix split_path_cygwin = Utils.split_path_cygwin split_path_win32 = Utils.split_path_win32 class Node(object): """ This class is organized in two parts * The basic methods meant for filesystem access (compute paths, create folders, etc) * The methods bound to a :py:class:`waflib.Build.BuildContext` (require ``bld.srcnode`` and ``bld.bldnode``) The Node objects are not thread safe in any way. """ dict_class = dict __slots__ = ('name', 'sig', 'children', 'parent', 'cache_abspath', 'cache_isdir', 'cache_sig') def __init__(self, name, parent): self.name = name self.parent = parent if parent: if name in parent.children: raise Errors.WafError('node %s exists in the parent files %r already' % (name, parent)) parent.children[name] = self def __setstate__(self, data): "Deserializes from data" self.name = data[0] self.parent = data[1] if data[2] is not None: # Issue 1480 self.children = self.dict_class(data[2]) if data[3] is not None: self.sig = data[3] def __getstate__(self): "Serialize the node info" return (self.name, self.parent, getattr(self, 'children', None), getattr(self, 'sig', None)) def __str__(self): "String representation (name), for debugging purposes" return self.name def __repr__(self): "String representation (abspath), for debugging purposes" return self.abspath() def __hash__(self): "Node hash, used for storage in dicts. This hash is not persistent." return id(self) def __eq__(self, node): "Node comparison, based on the IDs" return id(self) == id(node) def __copy__(self): "Implemented to prevent nodes from being copied (raises an exception)" raise Errors.WafError('nodes are not supposed to be copied') def read(self, flags='r', encoding='ISO8859-1'): """ Return the contents of the file represented by this node:: def build(bld): bld.path.find_node('wscript').read() :type fname: string :param fname: Path to file :type m: string :param m: Open mode :rtype: string :return: File contents """ return Utils.readf(self.abspath(), flags, encoding) def write(self, data, flags='w', encoding='ISO8859-1'): """ Write some text to the physical file represented by this node:: def build(bld): bld.path.make_node('foo.txt').write('Hello, world!') :type data: string :param data: data to write :type flags: string :param flags: Write mode """ Utils.writef(self.abspath(), data, flags, encoding) def read_json(self, convert=True, encoding='utf-8'): """ Read and parse the contents of this node as JSON:: def build(bld): bld.path.find_node('abc.json').read_json() Note that this by default automatically decodes unicode strings on Python2, unlike what the Python JSON module does. :type convert: boolean :param convert: Prevents decoding of unicode strings on Python2 :type encoding: string :param encoding: The encoding of the file to read. This default to UTF8 as per the JSON standard :rtype: object :return: Parsed file contents """ import json # Python 2.6 and up object_pairs_hook = None if convert and sys.hexversion < 0x3000000: try: _type = unicode except NameError: _type = str def convert(value): if isinstance(value, list): return [convert(element) for element in value] elif isinstance(value, _type): return str(value) else: return value def object_pairs(pairs): return dict((str(pair[0]), convert(pair[1])) for pair in pairs) object_pairs_hook = object_pairs return json.loads(self.read(encoding=encoding), object_pairs_hook=object_pairs_hook) def write_json(self, data, pretty=True): """ Writes a python object as JSON to disk. Files are always written as UTF8 as per the JSON standard:: def build(bld): bld.path.find_node('xyz.json').write_json(199) :type data: object :param data: The data to write to disk :type pretty: boolean :param pretty: Determines if the JSON will be nicely space separated """ import json # Python 2.6 and up indent = 2 separators = (',', ': ') sort_keys = pretty newline = os.linesep if not pretty: indent = None separators = (',', ':') newline = '' output = json.dumps(data, indent=indent, separators=separators, sort_keys=sort_keys) + newline self.write(output, encoding='utf-8') def chmod(self, val): """ Change file/dir permissions:: def build(bld): bld.path.chmod(493) # 0755 """ os.chmod(self.abspath(), val) def delete(self): """Delete the file/folder, and remove this node from the tree. Do not use this object after calling this method.""" try: try: if hasattr(self, 'children'): shutil.rmtree(self.abspath()) else: os.remove(self.abspath()) except OSError as e: if os.path.exists(self.abspath()): raise e finally: self.evict() def evict(self): """Internal - called when a node is removed""" del self.parent.children[self.name] def suffix(self): """Return the file extension""" k = max(0, self.name.rfind('.')) return self.name[k:] def height(self): """Depth in the folder hierarchy from the filesystem root or from all the file drives""" d = self val = -1 while d: d = d.parent val += 1 return val def listdir(self): """List the folder contents""" lst = Utils.listdir(self.abspath()) lst.sort() return lst def mkdir(self): """ Create a folder represented by this node, creating intermediate nodes as needed An exception will be raised only when the folder cannot possibly exist there """ if getattr(self, 'cache_isdir', None): return try: self.parent.mkdir() except OSError: pass if self.name: try: os.makedirs(self.abspath()) except OSError: pass if not os.path.isdir(self.abspath()): raise Errors.WafError('Could not create the directory %s' % self.abspath()) try: self.children except AttributeError: self.children = self.dict_class() self.cache_isdir = True def find_node(self, lst): """ Find a node on the file system (files or folders), create intermediate nodes as needed :param lst: path :type lst: string or list of string """ if isinstance(lst, str): lst = [x for x in split_path(lst) if x and x != '.'] cur = self for x in lst: if x == '..': cur = cur.parent or cur continue try: ch = cur.children except AttributeError: cur.children = self.dict_class() else: try: cur = ch[x] continue except KeyError: pass # optimistic: create the node first then look if it was correct to do so cur = self.__class__(x, cur) try: os.stat(cur.abspath()) except OSError: cur.evict() return None ret = cur try: os.stat(ret.abspath()) except OSError: ret.evict() return None try: while not getattr(cur.parent, 'cache_isdir', None): cur = cur.parent cur.cache_isdir = True except AttributeError: pass return ret def make_node(self, lst): """ Find or create a node without looking on the filesystem :param lst: path :type lst: string or list of string """ if isinstance(lst, str): lst = [x for x in split_path(lst) if x and x != '.'] cur = self for x in lst: if x == '..': cur = cur.parent or cur continue if getattr(cur, 'children', {}): if x in cur.children: cur = cur.children[x] continue else: cur.children = self.dict_class() cur = self.__class__(x, cur) return cur def search_node(self, lst): """ Search for a node without looking on the filesystem :param lst: path :type lst: string or list of string """ if isinstance(lst, str): lst = [x for x in split_path(lst) if x and x != '.'] cur = self for x in lst: if x == '..': cur = cur.parent or cur else: try: cur = cur.children[x] except (AttributeError, KeyError): return None return cur def path_from(self, node): """ Path of this node seen from the other:: def build(bld): n1 = bld.path.find_node('foo/bar/xyz.txt') n2 = bld.path.find_node('foo/stuff/') n1.path_from(n2) # '../bar/xyz.txt' :param node: path to use as a reference :type node: :py:class:`waflib.Node.Node` """ c1 = self c2 = node c1h = c1.height() c2h = c2.height() lst = [] up = 0 while c1h > c2h: lst.append(c1.name) c1 = c1.parent c1h -= 1 while c2h > c1h: up += 1 c2 = c2.parent c2h -= 1 while id(c1) != id(c2): lst.append(c1.name) up += 1 c1 = c1.parent c2 = c2.parent if c1.parent: for i in range(up): lst.append('..') else: if lst and not Utils.is_win32: lst.append('') lst.reverse() return os.sep.join(lst) or '.' def abspath(self): """ Absolute path. A cache is kept in the context as ``cache_node_abspath`` """ try: return self.cache_abspath except AttributeError: pass # think twice before touching this (performance + complexity + correctness) if not self.parent: val = os.sep elif not self.parent.name: val = os.sep + self.name else: val = self.parent.abspath() + os.sep + self.name self.cache_abspath = val return val if Utils.is_win32: def abspath(self): try: return self.cache_abspath except AttributeError: pass if not self.parent: val = '' elif not self.parent.name: val = self.name + os.sep else: val = self.parent.abspath().rstrip(os.sep) + os.sep + self.name self.cache_abspath = val return val def is_child_of(self, node): """ Does this node belong to the subtree node?:: def build(bld): node = bld.path.find_node('wscript') node.is_child_of(bld.path) # True :param node: path to use as a reference :type node: :py:class:`waflib.Node.Node` """ p = self diff = self.height() - node.height() while diff > 0: diff -= 1 p = p.parent return id(p) == id(node) def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remove=True): """ Semi-private and recursive method used by ant_glob. :param accept: function used for accepting/rejecting a node, returns the patterns that can be still accepted in recursion :type accept: function :param maxdepth: maximum depth in the filesystem (25) :type maxdepth: int :param pats: list of patterns to accept and list of patterns to exclude :type pats: tuple :param dir: return folders too (False by default) :type dir: bool :param src: return files (True by default) :type src: bool :param remove: remove files/folders that do not exist (True by default) :type remove: bool """ dircont = self.listdir() dircont.sort() try: lst = set(self.children.keys()) except AttributeError: self.children = self.dict_class() else: if remove: for x in lst - set(dircont): self.children[x].evict() for name in dircont: npats = accept(name, pats) if npats and npats[0]: accepted = [] in npats[0] node = self.make_node([name]) isdir = os.path.isdir(node.abspath()) if accepted: if isdir: if dir: yield node else: if src: yield node if getattr(node, 'cache_isdir', None) or isdir: node.cache_isdir = True if maxdepth: for k in node.ant_iter(accept=accept, maxdepth=maxdepth - 1, pats=npats, dir=dir, src=src, remove=remove): yield k raise StopIteration def ant_glob(self, *k, **kw): """ This method is used for finding files across folders. It behaves like ant patterns: * ``**/*`` find all files recursively * ``**/*.class`` find all files ending by .class * ``..`` find files having two dot characters For example:: def configure(cfg): cfg.path.ant_glob('**/*.cpp') # find all .cpp files cfg.root.ant_glob('etc/*.txt') # using the filesystem root can be slow cfg.path.ant_glob('*.cpp', excl=['*.c'], src=True, dir=False) For more information see http://ant.apache.org/manual/dirtasks.html The nodes that correspond to files and folders that do not exist will be removed. To prevent this behaviour, pass 'remove=False' :param incl: ant patterns or list of patterns to include :type incl: string or list of strings :param excl: ant patterns or list of patterns to exclude :type excl: string or list of strings :param dir: return folders too (False by default) :type dir: bool :param src: return files (True by default) :type src: bool :param remove: remove files/folders that do not exist (True by default) :type remove: bool :param maxdepth: maximum depth of recursion :type maxdepth: int :param ignorecase: ignore case while matching (False by default) :type ignorecase: bool """ src = kw.get('src', True) dir = kw.get('dir', False) excl = kw.get('excl', exclude_regs) incl = k and k[0] or kw.get('incl', '**') reflags = kw.get('ignorecase', 0) and re.I def to_pat(s): lst = Utils.to_list(s) ret = [] for x in lst: x = x.replace('\\', '/').replace('//', '/') if x.endswith('/'): x += '**' lst2 = x.split('/') accu = [] for k in lst2: if k == '**': accu.append(k) else: k = k.replace('.', '[.]').replace('*','.*').replace('?', '.').replace('+', '\\+') k = '^%s$' % k try: #print "pattern", k accu.append(re.compile(k, flags=reflags)) except Exception as e: raise Errors.WafError("Invalid pattern: %s" % k, e) ret.append(accu) return ret def filtre(name, nn): ret = [] for lst in nn: if not lst: pass elif lst[0] == '**': ret.append(lst) if len(lst) > 1: if lst[1].match(name): ret.append(lst[2:]) else: ret.append([]) elif lst[0].match(name): ret.append(lst[1:]) return ret def accept(name, pats): nacc = filtre(name, pats[0]) nrej = filtre(name, pats[1]) if [] in nrej: nacc = [] return [nacc, nrej] ret = [x for x in self.ant_iter(accept=accept, pats=[to_pat(incl), to_pat(excl)], maxdepth=kw.get('maxdepth', 25), dir=dir, src=src, remove=kw.get('remove', True))] if kw.get('flat', False): return ' '.join([x.path_from(self) for x in ret]) return ret # -------------------------------------------------------------------------------- # the following methods require the source/build folders (bld.srcnode/bld.bldnode) # using a subclass is a possibility, but is that really necessary? # -------------------------------------------------------------------------------- def is_src(self): """ True if the node is below the source directory note: !is_src does not imply is_bld() :rtype: bool """ cur = self x = id(self.ctx.srcnode) y = id(self.ctx.bldnode) while cur.parent: if id(cur) == y: return False if id(cur) == x: return True cur = cur.parent return False def is_bld(self): """ True if the node is below the build directory note: !is_bld does not imply is_src :rtype: bool """ cur = self y = id(self.ctx.bldnode) while cur.parent: if id(cur) == y: return True cur = cur.parent return False def get_src(self): """ Return the equivalent src node (or self if not possible) :rtype: :py:class:`waflib.Node.Node` """ cur = self x = id(self.ctx.srcnode) y = id(self.ctx.bldnode) lst = [] while cur.parent: if id(cur) == y: lst.reverse() return self.ctx.srcnode.make_node(lst) if id(cur) == x: return self lst.append(cur.name) cur = cur.parent return self def get_bld(self): """ Return the equivalent bld node (or self if not possible) :rtype: :py:class:`waflib.Node.Node` """ cur = self x = id(self.ctx.srcnode) y = id(self.ctx.bldnode) lst = [] while cur.parent: if id(cur) == y: return self if id(cur) == x: lst.reverse() return self.ctx.bldnode.make_node(lst) lst.append(cur.name) cur = cur.parent # the file is external to the current project, make a fake root in the current build directory lst.reverse() if lst and Utils.is_win32 and len(lst[0]) == 2 and lst[0].endswith(':'): lst[0] = lst[0][0] return self.ctx.bldnode.make_node(['__root__'] + lst) def find_resource(self, lst): """ Try to find a declared build node or a source file :param lst: path :type lst: string or list of string """ if isinstance(lst, str): lst = [x for x in split_path(lst) if x and x != '.'] node = self.get_bld().search_node(lst) if not node: self = self.get_src() node = self.find_node(lst) if node: if os.path.isdir(node.abspath()): return None return node def find_or_declare(self, lst): """ if 'self' is in build directory, try to return an existing node if no node is found, go to the source directory try to find an existing node in the source directory if no node is found, create it in the build directory :param lst: path :type lst: string or list of string """ if isinstance(lst, str): lst = [x for x in split_path(lst) if x and x != '.'] node = self.get_bld().search_node(lst) if node: if not os.path.isfile(node.abspath()): node.sig = None node.parent.mkdir() return node self = self.get_src() node = self.find_node(lst) if node: if not os.path.isfile(node.abspath()): node.sig = None node.parent.mkdir() return node node = self.get_bld().make_node(lst) node.parent.mkdir() return node def find_dir(self, lst): """ Search for a folder in the filesystem :param lst: path :type lst: string or list of string """ if isinstance(lst, str): lst = [x for x in split_path(lst) if x and x != '.'] node = self.find_node(lst) try: if not os.path.isdir(node.abspath()): return None except (OSError, AttributeError): # the node might be None, and raise an AttributeError return None return node # helpers for building things def change_ext(self, ext, ext_in=None): """ :return: A build node of the same path, but with a different extension :rtype: :py:class:`waflib.Node.Node` """ name = self.name if ext_in is None: k = name.rfind('.') if k >= 0: name = name[:k] + ext else: name = name + ext else: name = name[:- len(ext_in)] + ext return self.parent.find_or_declare([name]) def bldpath(self): "Path seen from the build directory default/src/foo.cpp" return self.path_from(self.ctx.bldnode) def srcpath(self): "Path seen from the source directory ../src/foo.cpp" return self.path_from(self.ctx.srcnode) def relpath(self): "If a file in the build directory, bldpath, else srcpath" cur = self x = id(self.ctx.bldnode) while cur.parent: if id(cur) == x: return self.bldpath() cur = cur.parent return self.srcpath() def bld_dir(self): "Build path without the file name" return self.parent.bldpath() def get_bld_sig(self): """ Node signature, assuming the file is in the build directory """ try: return self.cache_sig except AttributeError: pass if not self.is_bld() or self.ctx.bldnode is self.ctx.srcnode: self.sig = Utils.h_file(self.abspath()) self.cache_sig = ret = self.sig return ret pickle_lock = Utils.threading.Lock() """Lock mandatory for thread-safe node serialization""" class Nod3(Node): """Mandatory subclass for thread-safe node serialization""" pass # do not remove 1.9.12~dfsg/waflib/Tools/0000755000000000000000000000000013214314510013704 5ustar rootroot1.9.12~dfsg/waflib/Tools/waf_unit_test.py0000644000000000000000000001413513214314510017135 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Carlos Rafael Giani, 2006 # Thomas Nagy, 2010 """ Unit testing system for C/C++/D providing test execution: * in parallel, by using ``waf -j`` * partial (only the tests that have changed) or full (by using ``waf --alltests``) The tests are declared by adding the **test** feature to programs:: def options(opt): opt.load('compiler_cxx waf_unit_test') def configure(conf): conf.load('compiler_cxx waf_unit_test') def build(bld): bld(features='cxx cxxprogram test', source='main.cpp', target='app') # or bld.program(features='test', source='main2.cpp', target='app2') When the build is executed, the program 'test' will be built and executed without arguments. The success/failure is detected by looking at the return code. The status and the standard output/error are stored on the build context. The results can be displayed by registering a callback function. Here is how to call the predefined callback:: def build(bld): bld(features='cxx cxxprogram test', source='main.c', target='app') from waflib.Tools import waf_unit_test bld.add_post_fun(waf_unit_test.summary) """ import os from waflib.TaskGen import feature, after_method, taskgen_method from waflib import Utils, Task, Logs, Options testlock = Utils.threading.Lock() @feature('test') @after_method('apply_link') def make_test(self): """Create the unit test task. There can be only one unit test task by task generator.""" if getattr(self, 'link_task', None): self.create_task('utest', self.link_task.outputs) @taskgen_method def add_test_results(self, tup): """Override and return tup[1] to interrupt the build immediately if a test does not run""" Logs.debug("ut: %r", tup) self.utest_result = tup try: self.bld.utest_results.append(tup) except AttributeError: self.bld.utest_results = [tup] class utest(Task.Task): """ Execute a unit test """ color = 'PINK' after = ['vnum', 'inst'] vars = [] def runnable_status(self): """ Always execute the task if `waf --alltests` was used or no tests if ``waf --notests`` was used """ if getattr(Options.options, 'no_tests', False): return Task.SKIP_ME ret = super(utest, self).runnable_status() if ret == Task.SKIP_ME: if getattr(Options.options, 'all_tests', False): return Task.RUN_ME return ret def add_path(self, dct, path, var): dct[var] = os.pathsep.join(Utils.to_list(path) + [os.environ.get(var, '')]) def get_test_env(self): """ In general, tests may require any library built anywhere in the project. Override this method if fewer paths are needed """ try: fu = getattr(self.generator.bld, 'all_test_paths') except AttributeError: # this operation may be performed by at most #maxjobs fu = os.environ.copy() lst = [] for g in self.generator.bld.groups: for tg in g: if getattr(tg, 'link_task', None): s = tg.link_task.outputs[0].parent.abspath() if s not in lst: lst.append(s) if Utils.is_win32: self.add_path(fu, lst, 'PATH') elif Utils.unversioned_sys_platform() == 'darwin': self.add_path(fu, lst, 'DYLD_LIBRARY_PATH') self.add_path(fu, lst, 'LD_LIBRARY_PATH') else: self.add_path(fu, lst, 'LD_LIBRARY_PATH') self.generator.bld.all_test_paths = fu return fu def run(self): """ Execute the test. The execution is always successful, and the results are stored on ``self.generator.bld.utest_results`` for postprocessing. Override ``add_test_results`` to interrupt the build """ filename = self.inputs[0].abspath() self.ut_exec = getattr(self.generator, 'ut_exec', [filename]) if getattr(self.generator, 'ut_fun', None): self.generator.ut_fun(self) cwd = getattr(self.generator, 'ut_cwd', '') or self.inputs[0].parent.abspath() testcmd = getattr(self.generator, 'ut_cmd', False) or getattr(Options.options, 'testcmd', False) if testcmd: self.ut_exec = (testcmd % self.ut_exec[0]).split(' ') proc = Utils.subprocess.Popen(self.ut_exec, cwd=cwd, env=self.get_test_env(), stderr=Utils.subprocess.PIPE, stdout=Utils.subprocess.PIPE) (stdout, stderr) = proc.communicate() tup = (filename, proc.returncode, stdout, stderr) testlock.acquire() try: return self.generator.add_test_results(tup) finally: testlock.release() def summary(bld): """ Display an execution summary:: def build(bld): bld(features='cxx cxxprogram test', source='main.c', target='app') from waflib.Tools import waf_unit_test bld.add_post_fun(waf_unit_test.summary) """ lst = getattr(bld, 'utest_results', []) if lst: Logs.pprint('CYAN', 'execution summary') total = len(lst) tfail = len([x for x in lst if x[1]]) Logs.pprint('CYAN', ' tests that pass %d/%d' % (total-tfail, total)) for (f, code, out, err) in lst: if not code: Logs.pprint('CYAN', ' %s' % f) Logs.pprint('CYAN', ' tests that fail %d/%d' % (tfail, total)) for (f, code, out, err) in lst: if code: Logs.pprint('CYAN', ' %s' % f) def set_exit_code(bld): """ If any of the tests fail waf will exit with that exit code. This is useful if you have an automated build system which need to report on errors from the tests. You may use it like this: def build(bld): bld(features='cxx cxxprogram test', source='main.c', target='app') from waflib.Tools import waf_unit_test bld.add_post_fun(waf_unit_test.set_exit_code) """ lst = getattr(bld, 'utest_results', []) for (f, code, out, err) in lst: if code: msg = [] if out: msg.append('stdout:%s%s' % (os.linesep, out.decode('utf-8'))) if err: msg.append('stderr:%s%s' % (os.linesep, err.decode('utf-8'))) bld.fatal(os.linesep.join(msg)) def options(opt): """ Provide the ``--alltests``, ``--notests`` and ``--testcmd`` command-line options. """ opt.add_option('--notests', action='store_true', default=False, help='Exec no unit tests', dest='no_tests') opt.add_option('--alltests', action='store_true', default=False, help='Exec all unit tests', dest='all_tests') opt.add_option('--testcmd', action='store', default=False, help = 'Run the unit tests using the test-cmd string' ' example "--test-cmd="valgrind --error-exitcode=1' ' %s" to run under valgrind', dest='testcmd') 1.9.12~dfsg/waflib/Tools/c.py0000644000000000000000000000277713214314510014515 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) "Base for c programs/libraries" from waflib import TaskGen, Task from waflib.Tools import c_preproc from waflib.Tools.ccroot import link_task, stlink_task @TaskGen.extension('.c') def c_hook(self, node): "Bind the c file extension to the creation of a :py:class:`waflib.Tools.c.c` instance" if not self.env.CC and self.env.CXX: return self.create_compiled_task('cxx', node) return self.create_compiled_task('c', node) class c(Task.Task): "Compile C files into object files" run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()}' vars = ['CCDEPS'] # unused variable to depend on, just in case ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] scan = c_preproc.scan class cprogram(link_task): "Link object files into a c program" run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' ext_out = ['.bin'] vars = ['LINKDEPS'] inst_to = '${BINDIR}' class cshlib(cprogram): "Link object files into a c shared library" inst_to = '${LIBDIR}' class cstlib(stlink_task): "Link object files into a c static library" pass # do not remove 1.9.12~dfsg/waflib/Tools/icpc.py0000644000000000000000000000124613214314510015177 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy 2009-2010 (ita) """ Detect the Intel C++ compiler """ import sys from waflib.Tools import ccroot, ar, gxx from waflib.Configure import conf @conf def find_icpc(conf): """ Find the program icpc, and execute it to ensure it really is icpc """ if sys.platform == 'cygwin': conf.fatal('The Intel compiler does not work on Cygwin') cxx = conf.find_program('icpc', var='CXX') conf.get_cc_version(cxx, icc=True) conf.env.CXX_NAME = 'icc' def configure(conf): conf.find_icpc() conf.find_ar() conf.gxx_common_flags() conf.gxx_modifier_platform() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/msvc.py0000644000000000000000000011624513214314510015237 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Carlos Rafael Giani, 2006 (dv) # Tamas Pal, 2007 (folti) # Nicolas Mercier, 2009 # Matt Clarkson, 2012 """ Microsoft Visual C++/Intel C++ compiler support Usage:: $ waf configure --msvc_version="msvc 10.0,msvc 9.0" --msvc_target="x64" or:: def configure(conf): conf.env['MSVC_VERSIONS'] = ['msvc 10.0', 'msvc 9.0', 'msvc 8.0', 'msvc 7.1', 'msvc 7.0', 'msvc 6.0', 'wsdk 7.0', 'intel 11', 'PocketPC 9.0', 'Smartphone 8.0'] conf.env['MSVC_TARGETS'] = ['x64'] conf.load('msvc') or:: def configure(conf): conf.load('msvc', funs='no_autodetect') conf.check_lib_msvc('gdi32') conf.check_libs_msvc('kernel32 user32') def build(bld): tg = bld.program(source='main.c', target='app', use='KERNEL32 USER32 GDI32') Platforms and targets will be tested in the order they appear; the first good configuration will be used. To skip testing all the configurations that are not used, use the ``--msvc_lazy_autodetect`` option or set ``conf.env['MSVC_LAZY_AUTODETECT']=True``. Supported platforms: ia64, x64, x86, x86_amd64, x86_ia64, x86_arm, amd64_x86, amd64_arm Compilers supported: * msvc => Visual Studio, versions 6.0 (VC 98, VC .NET 2002) to 12.0 (Visual Studio 2013) * wsdk => Windows SDK, versions 6.0, 6.1, 7.0, 7.1, 8.0 * icl => Intel compiler, versions 9, 10, 11, 13 * winphone => Visual Studio to target Windows Phone 8 native (version 8.0 for now) * Smartphone => Compiler/SDK for Smartphone devices (armv4/v4i) * PocketPC => Compiler/SDK for PocketPC devices (armv4/v4i) To use WAF in a VS2008 Make file project (see http://code.google.com/p/waf/issues/detail?id=894) You may consider to set the environment variable "VS_UNICODE_OUTPUT" to nothing before calling waf. So in your project settings use something like 'cmd.exe /C "set VS_UNICODE_OUTPUT=& set PYTHONUNBUFFERED=true & waf build"'. cmd.exe /C "chcp 1252 & set PYTHONUNBUFFERED=true && set && waf configure" Setting PYTHONUNBUFFERED gives the unbuffered output. """ import os, sys, re, tempfile from waflib import Utils, Task, Logs, Options, Errors from waflib.Logs import debug, warn from waflib.TaskGen import after_method, feature from waflib.Configure import conf from waflib.Tools import ccroot, c, cxx, ar, winres g_msvc_systemlibs = ''' aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32 osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32 shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32 traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp '''.split() """importlibs provided by MSVC/Platform SDK. Do NOT search them""" all_msvc_platforms = [ ('x64', 'amd64'), ('x86', 'x86'), ('ia64', 'ia64'), ('x86_amd64', 'amd64'), ('x86_ia64', 'ia64'), ('x86_arm', 'arm'), ('amd64_x86', 'x86'), ('amd64_arm', 'arm') ] """List of msvc platforms""" all_wince_platforms = [ ('armv4', 'arm'), ('armv4i', 'arm'), ('mipsii', 'mips'), ('mipsii_fp', 'mips'), ('mipsiv', 'mips'), ('mipsiv_fp', 'mips'), ('sh4', 'sh'), ('x86', 'cex86') ] """List of wince platforms""" all_icl_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')] """List of icl platforms""" def options(opt): opt.add_option('--msvc_version', type='string', help = 'msvc version, eg: "msvc 10.0,msvc 9.0"', default='') opt.add_option('--msvc_targets', type='string', help = 'msvc targets, eg: "x64,arm"', default='') opt.add_option('--msvc_lazy_autodetect', action='store_true', help = 'lazily check msvc target environments') def setup_msvc(conf, versions, arch = False): """ Checks installed compilers and targets and returns the first combination from the user's options, env, or the global supported lists that checks. :param versions: A list of tuples of all installed compilers and available targets. :param arch: Whether to return the target architecture. :return: the compiler, revision, path, include dirs, library paths, and (optionally) target architecture :rtype: tuple of strings """ platforms = getattr(Options.options, 'msvc_targets', '').split(',') if platforms == ['']: platforms=Utils.to_list(conf.env['MSVC_TARGETS']) or [i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms] desired_versions = getattr(Options.options, 'msvc_version', '').split(',') if desired_versions == ['']: desired_versions = conf.env['MSVC_VERSIONS'] or [v for v,_ in versions][::-1] versiondict = dict(versions) for version in desired_versions: try: targets = dict(versiondict[version]) for target in platforms: try: try: realtarget,(p1,p2,p3) = targets[target] except conf.errors.ConfigurationError: # lazytup target evaluation errors del(targets[target]) else: compiler,revision = version.rsplit(' ', 1) if arch: return compiler,revision,p1,p2,p3,realtarget else: return compiler,revision,p1,p2,p3 except KeyError: continue except KeyError: continue conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)') @conf def get_msvc_version(conf, compiler, version, target, vcvars): """ Checks that an installed compiler actually runs and uses vcvars to obtain the environment needed by the compiler. :param compiler: compiler type, for looking up the executable name :param version: compiler version, for debugging only :param target: target architecture :param vcvars: batch file to run to check the environment :return: the location of the compiler executable, the location of include dirs, and the library paths :rtype: tuple of strings """ debug('msvc: get_msvc_version: %r %r %r', compiler, version, target) try: conf.msvc_cnt += 1 except AttributeError: conf.msvc_cnt = 1 batfile = conf.bldnode.make_node('waf-print-msvc-%d.bat' % conf.msvc_cnt) batfile.write("""@echo off set INCLUDE= set LIB= call "%s" %s echo PATH=%%PATH%% echo INCLUDE=%%INCLUDE%% echo LIB=%%LIB%%;%%LIBPATH%% """ % (vcvars,target)) sout = conf.cmd_and_log(['cmd.exe', '/E:on', '/V:on', '/C', batfile.abspath()]) lines = sout.splitlines() if not lines[0]: lines.pop(0) MSVC_PATH = MSVC_INCDIR = MSVC_LIBDIR = None for line in lines: if line.startswith('PATH='): path = line[5:] MSVC_PATH = path.split(';') elif line.startswith('INCLUDE='): MSVC_INCDIR = [i for i in line[8:].split(';') if i] elif line.startswith('LIB='): MSVC_LIBDIR = [i for i in line[4:].split(';') if i] if None in (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR): conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)') # Check if the compiler is usable at all. # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run. env = dict(os.environ) env.update(PATH = path) compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) cxx = conf.find_program(compiler_name, path_list=MSVC_PATH) # delete CL if exists. because it could contain parameters wich can change cl's behaviour rather catastrophically. if 'CL' in env: del(env['CL']) try: try: conf.cmd_and_log(cxx + ['/help'], env=env) except UnicodeError: st = Utils.ex_stack() if conf.logger: conf.logger.error(st) conf.fatal('msvc: Unicode error - check the code page?') except Exception as e: debug('msvc: get_msvc_version: %r %r %r -> failure %s' % (compiler, version, target, str(e))) conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)') else: debug('msvc: get_msvc_version: %r %r %r -> OK', compiler, version, target) finally: conf.env[compiler_name] = '' return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) @conf def gather_wsdk_versions(conf, versions): """ Use winreg to add the msvc versions to the input list :param versions: list to modify :type versions: list """ version_pattern = re.compile('^v..?.?\...?.?') try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows') except WindowsError: try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows') except WindowsError: return index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except WindowsError: break index = index + 1 if not version_pattern.match(version): continue try: msvc_version = Utils.winreg.OpenKey(all_versions, version) path,type = Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder') except WindowsError: continue if path and os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')): targets = [] for target,arch in all_msvc_platforms: try: targets.append((target, (arch, get_compiler_env(conf, 'wsdk', version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd'))))) except conf.errors.ConfigurationError: pass versions.append(('wsdk ' + version[1:], targets)) def gather_wince_supported_platforms(): """ Checks SmartPhones SDKs :param versions: list to modify :type versions: list """ supported_wince_platforms = [] try: ce_sdk = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs') except WindowsError: try: ce_sdk = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs') except WindowsError: ce_sdk = '' if not ce_sdk: return supported_wince_platforms ce_index = 0 while 1: try: sdk_device = Utils.winreg.EnumKey(ce_sdk, ce_index) except WindowsError: break ce_index = ce_index + 1 sdk = Utils.winreg.OpenKey(ce_sdk, sdk_device) try: path,type = Utils.winreg.QueryValueEx(sdk, 'SDKRootDir') except WindowsError: try: path,type = Utils.winreg.QueryValueEx(sdk,'SDKInformation') path,xml = os.path.split(path) except WindowsError: continue path=str(path) path,device = os.path.split(path) if not device: path,device = os.path.split(path) platforms = [] for arch,compiler in all_wince_platforms: if os.path.isdir(os.path.join(path, device, 'Lib', arch)): platforms.append((arch, compiler, os.path.join(path, device, 'Include', arch), os.path.join(path, device, 'Lib', arch))) if platforms: supported_wince_platforms.append((device, platforms)) return supported_wince_platforms def gather_msvc_detected_versions(): #Detected MSVC versions! version_pattern = re.compile('^(\d\d?\.\d\d?)(Exp)?$') detected_versions = [] for vcver,vcvar in (('VCExpress','Exp'), ('VisualStudio','')): try: prefix = 'SOFTWARE\\Wow6432node\\Microsoft\\'+vcver all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, prefix) except WindowsError: try: prefix = 'SOFTWARE\\Microsoft\\'+vcver all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, prefix) except WindowsError: continue index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except WindowsError: break index = index + 1 match = version_pattern.match(version) if not match: continue else: versionnumber = float(match.group(1)) detected_versions.append((versionnumber, version+vcvar, prefix+"\\"+version)) def fun(tup): return tup[0] detected_versions.sort(key = fun) return detected_versions def get_compiler_env(conf, compiler, version, bat_target, bat, select=None): """ Gets the compiler environment variables as a tuple. Evaluation is eager by default. If set to lazy with ``--msvc_lazy_autodetect`` or ``env.MSVC_LAZY_AUTODETECT`` the environment is evaluated when the tuple is destructured or iterated. This means destructuring can throw :py:class:`conf.errors.ConfigurationError`. :param conf: configuration context to use to eventually get the version environment :param compiler: compiler name :param version: compiler version number :param bat: path to the batch file to run :param select: optional function to take the realized environment variables tup and map it (e.g. to combine other constant paths) """ lazy = getattr(Options.options, 'msvc_lazy_autodetect', False) or conf.env['MSVC_LAZY_AUTODETECT'] def msvc_thunk(): vs = conf.get_msvc_version(compiler, version, bat_target, bat) if select: return select(vs) else: return vs return lazytup(msvc_thunk, lazy, ([], [], [])) class lazytup(object): """ A tuple that evaluates its elements from a function when iterated or destructured. :param fn: thunk to evaluate the tuple on demand :param lazy: whether to delay evaluation or evaluate in the constructor :param default: optional default for :py:func:`repr` if it should not evaluate """ def __init__(self, fn, lazy=True, default=None): self.fn = fn self.default = default if not lazy: self.evaluate() def __len__(self): self.evaluate() return len(self.value) def __iter__(self): self.evaluate() for i, v in enumerate(self.value): yield v def __getitem__(self, i): self.evaluate() return self.value[i] def __repr__(self): if hasattr(self, 'value'): return repr(self.value) elif self.default: return repr(self.default) else: self.evaluate() return repr(self.value) def evaluate(self): if hasattr(self, 'value'): return self.value = self.fn() @conf def gather_msvc_targets(conf, versions, version, vc_path): #Looking for normal MSVC compilers! targets = [] if os.path.isfile(os.path.join(vc_path, 'vcvarsall.bat')): for target,realtarget in all_msvc_platforms[::-1]: try: targets.append((target, (realtarget, get_compiler_env(conf, 'msvc', version, target, os.path.join(vc_path, 'vcvarsall.bat'))))) except conf.errors.ConfigurationError: pass elif os.path.isfile(os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')): try: targets.append(('x86', ('x86', get_compiler_env(conf, 'msvc', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat'))))) except conf.errors.ConfigurationError: pass elif os.path.isfile(os.path.join(vc_path, 'Bin', 'vcvars32.bat')): try: targets.append(('x86', ('x86', get_compiler_env(conf, 'msvc', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat'))))) except conf.errors.ConfigurationError: pass if targets: versions.append(('msvc '+ version, targets)) @conf def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms): #Looking for Win CE compilers! for device,platforms in supported_platforms: cetargets = [] for platform,compiler,include,lib in platforms: winCEpath = os.path.join(vc_path, 'ce') if not os.path.isdir(winCEpath): continue if os.path.isdir(os.path.join(winCEpath, 'lib', platform)): bindirs = [os.path.join(winCEpath, 'bin', compiler), os.path.join(winCEpath, 'bin', 'x86_'+compiler)] incdirs = [os.path.join(winCEpath, 'include'), os.path.join(winCEpath, 'atlmfc', 'include'), include] libdirs = [os.path.join(winCEpath, 'lib', platform), os.path.join(winCEpath, 'atlmfc', 'lib', platform), lib] def combine_common(compiler_env): (common_bindirs,_1,_2) = compiler_env return (bindirs + common_bindirs, incdirs, libdirs) try: cetargets.append((platform, (platform, get_compiler_env(conf, 'msvc', version, 'x86', vsvars, combine_common)))) except conf.errors.ConfigurationError: continue if cetargets: versions.append((device + ' ' + version, cetargets)) @conf def gather_winphone_targets(conf, versions, version, vc_path, vsvars): #Looking for WinPhone compilers targets = [] for target,realtarget in all_msvc_platforms[::-1]: try: targets.append((target, (realtarget, get_compiler_env(conf, 'winphone', version, target, vsvars)))) except conf.errors.ConfigurationError: pass if targets: versions.append(('winphone '+ version, targets)) @conf def gather_msvc_versions(conf, versions): vc_paths = [] for (v,version,reg) in gather_msvc_detected_versions(): try: try: msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\VC") except WindowsError: msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\Microsoft Visual C++") path,type = Utils.winreg.QueryValueEx(msvc_version, 'ProductDir') vc_paths.append((version, os.path.abspath(str(path)))) except WindowsError: continue wince_supported_platforms = gather_wince_supported_platforms() for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) vsvars = os.path.join(vs_path, 'Common7', 'Tools', 'vsvars32.bat') if wince_supported_platforms and os.path.isfile(vsvars): conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms) # WP80 works with 11.0Exp and 11.0, both of which resolve to the same vc_path. # Stop after one is found. for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) vsvars = os.path.join(vs_path, 'VC', 'WPSDK', 'WP80', 'vcvarsphoneall.bat') if os.path.isfile(vsvars): conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars) break for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) conf.gather_msvc_targets(versions, version, vc_path) @conf def gather_icl_versions(conf, versions): """ Checks ICL compilers :param versions: list to modify :type versions: list """ version_pattern = re.compile('^...?.?\....?.?') try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++') except WindowsError: try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\C++') except WindowsError: return index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except WindowsError: break index = index + 1 if not version_pattern.match(version): continue targets = [] for target,arch in all_icl_platforms: try: if target=='intel64': targetDir='EM64T_NATIVE' else: targetDir=target Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) icl_version=Utils.winreg.OpenKey(all_versions,version) path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file)))) except conf.errors.ConfigurationError: pass except WindowsError: pass for target,arch in all_icl_platforms: try: icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target) path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir') batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: targets.append((target, (arch, get_compiler_env(conf, 'intel', version, target, batch_file)))) except conf.errors.ConfigurationError: pass except WindowsError: continue major = version[0:2] versions.append(('intel ' + major, targets)) @conf def gather_intel_composer_versions(conf, versions): """ Checks ICL compilers that are part of Intel Composer Suites :param versions: list to modify :type versions: list """ version_pattern = re.compile('^...?.?\...?.?.?') try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Suites') except WindowsError: try: all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Suites') except WindowsError: return index = 0 while 1: try: version = Utils.winreg.EnumKey(all_versions, index) except WindowsError: break index = index + 1 if not version_pattern.match(version): continue targets = [] for target,arch in all_icl_platforms: try: if target=='intel64': targetDir='EM64T_NATIVE' else: targetDir=target try: defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir) except WindowsError: if targetDir=='EM64T_NATIVE': defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T') else: raise WindowsError uid,type = Utils.winreg.QueryValueEx(defaults, 'SubKey') Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir) icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++') path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file)))) except conf.errors.ConfigurationError: pass # The intel compilervar_arch.bat is broken when used with Visual Studio Express 2012 # http://software.intel.com/en-us/forums/topic/328487 compilervars_warning_attr = '_compilervars_warning_key' if version[0:2] == '13' and getattr(conf, compilervars_warning_attr, True): setattr(conf, compilervars_warning_attr, False) patch_url = 'http://software.intel.com/en-us/forums/topic/328487' compilervars_arch = os.path.join(path, 'bin', 'compilervars_arch.bat') for vscomntool in ('VS110COMNTOOLS', 'VS100COMNTOOLS'): if vscomntool in os.environ: vs_express_path = os.environ[vscomntool] + r'..\IDE\VSWinExpress.exe' dev_env_path = os.environ[vscomntool] + r'..\IDE\devenv.exe' if (r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"' in Utils.readf(compilervars_arch) and not os.path.exists(vs_express_path) and not os.path.exists(dev_env_path)): Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ' '(VSWinExpress.exe) but it does not seem to be installed at %r. ' 'The intel command line set up will fail to configure unless the file %r' 'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url)) except WindowsError: pass major = version[0:2] versions.append(('intel ' + major, targets)) @conf def get_msvc_versions(conf, eval_and_save=True): """ :return: list of compilers installed :rtype: list of string """ if conf.env['MSVC_INSTALLED_VERSIONS']: return conf.env['MSVC_INSTALLED_VERSIONS'] # Gather all the compiler versions and targets. This phase can be lazy # per lazy detection settings. lst = [] conf.gather_icl_versions(lst) conf.gather_intel_composer_versions(lst) conf.gather_wsdk_versions(lst) conf.gather_msvc_versions(lst) # Override lazy detection by evaluating after the fact. if eval_and_save: def checked_target(t): target,(arch,paths) = t try: paths.evaluate() except conf.errors.ConfigurationError: return None else: return t lst = [(version, list(filter(checked_target, targets))) for version, targets in lst] conf.env['MSVC_INSTALLED_VERSIONS'] = lst return lst @conf def print_all_msvc_detected(conf): """ Print the contents of *conf.env.MSVC_INSTALLED_VERSIONS* """ for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']: Logs.info(version) for target,l in targets: Logs.info("\t"+target) @conf def detect_msvc(conf, arch = False): # Save installed versions only if lazy detection is disabled. lazy_detect = getattr(Options.options, 'msvc_lazy_autodetect', False) or conf.env['MSVC_LAZY_AUTODETECT'] versions = get_msvc_versions(conf, not lazy_detect) return setup_msvc(conf, versions, arch) @conf def find_lt_names_msvc(self, libname, is_static=False): """ Win32/MSVC specific code to glean out information from libtool la files. this function is not attached to the task_gen class """ lt_names=[ 'lib%s.la' % libname, '%s.la' % libname, ] for path in self.env['LIBPATH']: for la in lt_names: laf=os.path.join(path,la) dll=None if os.path.exists(laf): ltdict = Utils.read_la_file(laf) lt_libdir=None if ltdict.get('libdir', ''): lt_libdir = ltdict['libdir'] if not is_static and ltdict.get('library_names', ''): dllnames=ltdict['library_names'].split() dll=dllnames[0].lower() dll=re.sub('\.dll$', '', dll) return (lt_libdir, dll, False) elif ltdict.get('old_library', ''): olib=ltdict['old_library'] if os.path.exists(os.path.join(path,olib)): return (path, olib, True) elif lt_libdir != '' and os.path.exists(os.path.join(lt_libdir,olib)): return (lt_libdir, olib, True) else: return (None, olib, True) else: raise self.errors.WafError('invalid libtool object file: %s' % laf) return (None, None, None) @conf def libname_msvc(self, libname, is_static=False): lib = libname.lower() lib = re.sub('\.lib$','',lib) if lib in g_msvc_systemlibs: return lib lib=re.sub('^lib','',lib) if lib == 'm': return None (lt_path, lt_libname, lt_static) = self.find_lt_names_msvc(lib, is_static) if lt_path != None and lt_libname != None: if lt_static == True: # file existance check has been made by find_lt_names return os.path.join(lt_path,lt_libname) if lt_path != None: _libpaths=[lt_path] + self.env['LIBPATH'] else: _libpaths=self.env['LIBPATH'] static_libs=[ 'lib%ss.lib' % lib, 'lib%s.lib' % lib, '%ss.lib' % lib, '%s.lib' %lib, ] dynamic_libs=[ 'lib%s.dll.lib' % lib, 'lib%s.dll.a' % lib, '%s.dll.lib' % lib, '%s.dll.a' % lib, 'lib%s_d.lib' % lib, '%s_d.lib' % lib, '%s.lib' %lib, ] libnames=static_libs if not is_static: libnames=dynamic_libs + static_libs for path in _libpaths: for libn in libnames: if os.path.exists(os.path.join(path, libn)): debug('msvc: lib found: %s' % os.path.join(path,libn)) return re.sub('\.lib$', '',libn) #if no lib can be found, just return the libname as msvc expects it self.fatal("The library %r could not be found" % libname) return re.sub('\.lib$', '', libname) @conf def check_lib_msvc(self, libname, is_static=False, uselib_store=None): """ Ideally we should be able to place the lib in the right env var, either STLIB or LIB, but we don't distinguish static libs from shared libs. This is ok since msvc doesn't have any special linker flag to select static libs (no env['STLIB_MARKER']) """ libn = self.libname_msvc(libname, is_static) if not uselib_store: uselib_store = libname.upper() if False and is_static: # disabled self.env['STLIB_' + uselib_store] = [libn] else: self.env['LIB_' + uselib_store] = [libn] @conf def check_libs_msvc(self, libnames, is_static=False): for libname in Utils.to_list(libnames): self.check_lib_msvc(libname, is_static) def configure(conf): """ Configuration methods to call for detecting msvc """ conf.autodetect(True) conf.find_msvc() conf.msvc_common_flags() conf.cc_load_tools() conf.cxx_load_tools() conf.cc_add_flags() conf.cxx_add_flags() conf.link_add_flags() conf.visual_studio_add_flags() @conf def no_autodetect(conf): conf.env.NO_MSVC_DETECT = 1 configure(conf) @conf def autodetect(conf, arch = False): v = conf.env if v.NO_MSVC_DETECT: return if arch: compiler, version, path, includes, libdirs, arch = conf.detect_msvc(True) v['DEST_CPU'] = arch else: compiler, version, path, includes, libdirs = conf.detect_msvc() v['PATH'] = path v['INCLUDES'] = includes v['LIBPATH'] = libdirs v['MSVC_COMPILER'] = compiler try: v['MSVC_VERSION'] = float(version) except Exception: v['MSVC_VERSION'] = float(version[:-3]) def _get_prog_names(conf, compiler): if compiler=='intel': compiler_name = 'ICL' linker_name = 'XILINK' lib_name = 'XILIB' else: # assumes CL.exe compiler_name = 'CL' linker_name = 'LINK' lib_name = 'LIB' return compiler_name, linker_name, lib_name @conf def find_msvc(conf): """Due to path format limitations, limit operation only to native Win32. Yeah it sucks.""" if sys.platform == 'cygwin': conf.fatal('MSVC module does not work under cygwin Python!') # the autodetection is supposed to be performed before entering in this method v = conf.env path = v['PATH'] compiler = v['MSVC_COMPILER'] version = v['MSVC_VERSION'] compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) v.MSVC_MANIFEST = (compiler == 'msvc' and version >= 8) or (compiler == 'wsdk' and version >= 6) or (compiler == 'intel' and version >= 11) # compiler cxx = conf.find_program(compiler_name, var='CXX', path_list=path) # before setting anything, check if the compiler is really msvc env = dict(conf.environ) if path: env.update(PATH = ';'.join(path)) if not conf.cmd_and_log(cxx + ['/nologo', '/help'], env=env): conf.fatal('the msvc compiler could not be identified') # c/c++ compiler v['CC'] = v['CXX'] = cxx v['CC_NAME'] = v['CXX_NAME'] = 'msvc' # linker if not v['LINK_CXX']: link = conf.find_program(linker_name, path_list=path) if link: v['LINK_CXX'] = link else: conf.fatal('%s was not found (linker)' % linker_name) v['LINK'] = link if not v['LINK_CC']: v['LINK_CC'] = v['LINK_CXX'] # staticlib linker if not v['AR']: stliblink = conf.find_program(lib_name, path_list=path, var='AR') if not stliblink: return v['ARFLAGS'] = ['/NOLOGO'] # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later if v.MSVC_MANIFEST: conf.find_program('MT', path_list=path, var='MT') v['MTFLAGS'] = ['/NOLOGO'] try: conf.load('winres') except Errors.WafError: warn('Resource compiler not found. Compiling resource file is disabled') @conf def visual_studio_add_flags(self): """visual studio flags found in the system environment""" v = self.env try: v.prepend_value('INCLUDES', [x for x in self.environ['INCLUDE'].split(';') if x]) # notice the 'S' except Exception: pass try: v.prepend_value('LIBPATH', [x for x in self.environ['LIB'].split(';') if x]) except Exception: pass @conf def msvc_common_flags(conf): """ Setup the flags required for executing the msvc compiler """ v = conf.env v['DEST_BINFMT'] = 'pe' v.append_value('CFLAGS', ['/nologo']) v.append_value('CXXFLAGS', ['/nologo']) v['DEFINES_ST'] = '/D%s' v['CC_SRC_F'] = '' v['CC_TGT_F'] = ['/c', '/Fo'] v['CXX_SRC_F'] = '' v['CXX_TGT_F'] = ['/c', '/Fo'] if (v.MSVC_COMPILER == 'msvc' and v.MSVC_VERSION >= 8) or (v.MSVC_COMPILER == 'wsdk' and v.MSVC_VERSION >= 6): v['CC_TGT_F']= ['/FC'] + v['CC_TGT_F'] v['CXX_TGT_F']= ['/FC'] + v['CXX_TGT_F'] v['CPPPATH_ST'] = '/I%s' # template for adding include paths v['AR_TGT_F'] = v['CCLNK_TGT_F'] = v['CXXLNK_TGT_F'] = '/OUT:' # Subsystem specific flags v['CFLAGS_CONSOLE'] = v['CXXFLAGS_CONSOLE'] = ['/SUBSYSTEM:CONSOLE'] v['CFLAGS_NATIVE'] = v['CXXFLAGS_NATIVE'] = ['/SUBSYSTEM:NATIVE'] v['CFLAGS_POSIX'] = v['CXXFLAGS_POSIX'] = ['/SUBSYSTEM:POSIX'] v['CFLAGS_WINDOWS'] = v['CXXFLAGS_WINDOWS'] = ['/SUBSYSTEM:WINDOWS'] v['CFLAGS_WINDOWSCE'] = v['CXXFLAGS_WINDOWSCE'] = ['/SUBSYSTEM:WINDOWSCE'] # CRT specific flags v['CFLAGS_CRT_MULTITHREADED'] = v['CXXFLAGS_CRT_MULTITHREADED'] = ['/MT'] v['CFLAGS_CRT_MULTITHREADED_DLL'] = v['CXXFLAGS_CRT_MULTITHREADED_DLL'] = ['/MD'] v['CFLAGS_CRT_MULTITHREADED_DBG'] = v['CXXFLAGS_CRT_MULTITHREADED_DBG'] = ['/MTd'] v['CFLAGS_CRT_MULTITHREADED_DLL_DBG'] = v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG'] = ['/MDd'] # linker v['LIB_ST'] = '%s.lib' # template for adding shared libs v['LIBPATH_ST'] = '/LIBPATH:%s' # template for adding libpaths v['STLIB_ST'] = '%s.lib' v['STLIBPATH_ST'] = '/LIBPATH:%s' v.append_value('LINKFLAGS', ['/NOLOGO']) if v['MSVC_MANIFEST']: v.append_value('LINKFLAGS', ['/MANIFEST']) # shared library v['CFLAGS_cshlib'] = [] v['CXXFLAGS_cxxshlib'] = [] v['LINKFLAGS_cshlib'] = v['LINKFLAGS_cxxshlib'] = ['/DLL'] v['cshlib_PATTERN'] = v['cxxshlib_PATTERN'] = '%s.dll' v['implib_PATTERN'] = '%s.lib' v['IMPLIB_ST'] = '/IMPLIB:%s' # static library v['LINKFLAGS_cstlib'] = [] v['cstlib_PATTERN'] = v['cxxstlib_PATTERN'] = '%s.lib' # program v['cprogram_PATTERN'] = v['cxxprogram_PATTERN'] = '%s.exe' ####################################################################################################### ##### conf above, build below @after_method('apply_link') @feature('c', 'cxx') def apply_flags_msvc(self): """ Add additional flags implied by msvc, such as subsystems and pdb files:: def build(bld): bld.stlib(source='main.c', target='bar', subsystem='gruik') """ if self.env.CC_NAME != 'msvc' or not getattr(self, 'link_task', None): return is_static = isinstance(self.link_task, ccroot.stlink_task) subsystem = getattr(self, 'subsystem', '') if subsystem: subsystem = '/subsystem:%s' % subsystem flags = is_static and 'ARFLAGS' or 'LINKFLAGS' self.env.append_value(flags, subsystem) if not is_static: for f in self.env.LINKFLAGS: d = f.lower() if d[1:] == 'debug': pdbnode = self.link_task.outputs[0].change_ext('.pdb') self.link_task.outputs.append(pdbnode) if getattr(self, 'install_task', None): self.pdb_install_task = self.bld.install_files(self.install_task.dest, pdbnode, env=self.env) break # split the manifest file processing from the link task, like for the rc processing @feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib') @after_method('apply_link') def apply_manifest(self): """ Special linker for MSVC with support for embedding manifests into DLL's and executables compiled by Visual Studio 2005 or probably later. Without the manifest file, the binaries are unusable. See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx """ if self.env.CC_NAME == 'msvc' and self.env.MSVC_MANIFEST and getattr(self, 'link_task', None): out_node = self.link_task.outputs[0] man_node = out_node.parent.find_or_declare(out_node.name + '.manifest') self.link_task.outputs.append(man_node) self.link_task.do_manifest = True def exec_mf(self): """ Create the manifest file """ env = self.env mtool = env['MT'] if not mtool: return 0 self.do_manifest = False outfile = self.outputs[0].abspath() manifest = None for out_node in self.outputs: if out_node.name.endswith('.manifest'): manifest = out_node.abspath() break if manifest is None: # Should never get here. If we do, it means the manifest file was # never added to the outputs list, thus we don't have a manifest file # to embed, so we just return. return 0 # embedding mode. Different for EXE's and DLL's. # see: http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx mode = '' if 'cprogram' in self.generator.features or 'cxxprogram' in self.generator.features: mode = '1' elif 'cshlib' in self.generator.features or 'cxxshlib' in self.generator.features: mode = '2' debug('msvc: embedding manifest in mode %r' % mode) lst = [] + mtool lst.extend(Utils.to_list(env['MTFLAGS'])) lst.extend(['-manifest', manifest]) lst.append('-outputresource:%s;%s' % (outfile, mode)) return self.exec_command(lst) def quote_response_command(self, flag): if flag.find(' ') > -1: for x in ('/LIBPATH:', '/IMPLIB:', '/OUT:', '/I'): if flag.startswith(x): flag = '%s"%s"' % (x, flag[len(x):]) break else: flag = '"%s"' % flag return flag def exec_response_command(self, cmd, **kw): # not public yet try: tmp = None if sys.platform.startswith('win') and isinstance(cmd, list) and len(' '.join(cmd)) >= 8192: program = cmd[0] #unquoted program name, otherwise exec_command will fail cmd = [self.quote_response_command(x) for x in cmd] (fd, tmp) = tempfile.mkstemp() os.write(fd, '\r\n'.join(i.replace('\\', '\\\\') for i in cmd[1:]).encode()) os.close(fd) cmd = [program, '@' + tmp] # no return here, that's on purpose ret = self.generator.bld.exec_command(cmd, **kw) finally: if tmp: try: os.remove(tmp) except OSError: pass # anti-virus and indexers can keep the files open -_- return ret ########## stupid evil command modification: concatenate the tokens /Fx, /doc, and /x: with the next token def exec_command_msvc(self, *k, **kw): """ Change the command-line execution for msvc programs. Instead of quoting all the paths and keep using the shell, we can just join the options msvc is interested in """ if isinstance(k[0], list): lst = [] carry = '' for a in k[0]: if a == '/Fo' or a == '/doc' or a[-1] == ':': carry = a else: lst.append(carry + a) carry = '' k = [lst] if self.env['PATH']: env = dict(self.env.env or os.environ) env.update(PATH = ';'.join(self.env['PATH'])) kw['env'] = env bld = self.generator.bld try: if not kw.get('cwd', None): kw['cwd'] = bld.cwd except AttributeError: bld.cwd = kw['cwd'] = bld.variant_dir ret = self.exec_response_command(k[0], **kw) if not ret and getattr(self, 'do_manifest', None): ret = self.exec_mf() return ret def wrap_class(class_name): """ Manifest file processing and @response file workaround for command-line length limits on Windows systems The indicated task class is replaced by a subclass to prevent conflicts in case the class is wrapped more than once """ cls = Task.classes.get(class_name, None) if not cls: return None derived_class = type(class_name, (cls,), {}) def exec_command(self, *k, **kw): if self.env['CC_NAME'] == 'msvc': return self.exec_command_msvc(*k, **kw) else: return super(derived_class, self).exec_command(*k, **kw) # Chain-up monkeypatch needed since exec_command() is in base class API derived_class.exec_command = exec_command # No chain-up behavior needed since the following methods aren't in # base class API derived_class.exec_response_command = exec_response_command derived_class.quote_response_command = quote_response_command derived_class.exec_command_msvc = exec_command_msvc derived_class.exec_mf = exec_mf if hasattr(cls, 'hcode'): derived_class.hcode = cls.hcode return derived_class for k in 'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split(): wrap_class(k) def make_winapp(self, family): append = self.env.append_unique append('DEFINES', 'WINAPI_FAMILY=%s' % family) append('CXXFLAGS', '/ZW') append('CXXFLAGS', '/TP') for lib_path in self.env.LIBPATH: append('CXXFLAGS','/AI%s'%lib_path) @feature('winphoneapp') @after_method('process_use') @after_method('propagate_uselib_vars') def make_winphone_app(self): """ Insert configuration flags for windows phone applications (adds /ZW, /TP...) """ make_winapp(self, 'WINAPI_FAMILY_PHONE_APP') conf.env.append_unique('LINKFLAGS', '/NODEFAULTLIB:ole32.lib') conf.env.append_unique('LINKFLAGS', 'PhoneAppModelHost.lib') @feature('winapp') @after_method('process_use') @after_method('propagate_uselib_vars') def make_windows_app(self): """ Insert configuration flags for windows applications (adds /ZW, /TP...) """ make_winapp(self, 'WINAPI_FAMILY_DESKTOP_APP') 1.9.12~dfsg/waflib/Tools/errcheck.py0000644000000000000000000001572013214314510016051 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2011 (ita) """ errcheck: highlight common mistakes There is a performance hit, so this tool is only loaded when running "waf -v" """ typos = { 'feature':'features', 'sources':'source', 'targets':'target', 'include':'includes', 'export_include':'export_includes', 'define':'defines', 'importpath':'includes', 'installpath':'install_path', 'iscopy':'is_copy', } meths_typos = ['__call__', 'program', 'shlib', 'stlib', 'objects'] import sys from waflib import Logs, Build, Node, Task, TaskGen, ConfigSet, Errors, Utils import waflib.Tools.ccroot def check_same_targets(self): mp = Utils.defaultdict(list) uids = {} def check_task(tsk): if not isinstance(tsk, Task.Task): return for node in tsk.outputs: mp[node].append(tsk) try: uids[tsk.uid()].append(tsk) except KeyError: uids[tsk.uid()] = [tsk] for g in self.groups: for tg in g: try: for tsk in tg.tasks: check_task(tsk) except AttributeError: # raised if not a task generator, which should be uncommon check_task(tg) dupe = False for (k, v) in mp.items(): if len(v) > 1: dupe = True msg = '* Node %r is created more than once%s. The task generators are:' % (k, Logs.verbose == 1 and " (full message on 'waf -v -v')" or "") Logs.error(msg) for x in v: if Logs.verbose > 1: Logs.error(' %d. %r' % (1 + v.index(x), x.generator)) else: Logs.error(' %d. %r in %r' % (1 + v.index(x), x.generator.name, getattr(x.generator, 'path', None))) if not dupe: for (k, v) in uids.items(): if len(v) > 1: Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid') for tsk in v: Logs.error(' - object %r (%r) defined in %r' % (tsk.__class__.__name__, tsk, tsk.generator)) def check_invalid_constraints(self): feat = set([]) for x in list(TaskGen.feats.values()): feat.union(set(x)) for (x, y) in TaskGen.task_gen.prec.items(): feat.add(x) feat.union(set(y)) ext = set([]) for x in TaskGen.task_gen.mappings.values(): ext.add(x.__name__) invalid = ext & feat if invalid: Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method' % list(invalid)) # the build scripts have been read, so we can check for invalid after/before attributes on task classes for cls in list(Task.classes.values()): if sys.hexversion > 0x3000000 and issubclass(cls, Task.Task) and isinstance(cls.hcode, str): raise Errors.WafError('Class %r has hcode value %r of type , expecting (use Utils.h_cmd() ?)' % (cls, cls.hcode)) for x in ('before', 'after'): for y in Utils.to_list(getattr(cls, x, [])): if not Task.classes.get(y, None): Logs.error('Erroneous order constraint %r=%r on task class %r' % (x, y, cls.__name__)) if getattr(cls, 'rule', None): Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")' % cls.__name__) def replace(m): """ We could add properties, but they would not work in some cases: bld.program(...) requires 'source' in the attributes """ oldcall = getattr(Build.BuildContext, m) def call(self, *k, **kw): ret = oldcall(self, *k, **kw) for x in typos: if x in kw: if x == 'iscopy' and 'subst' in getattr(self, 'features', ''): continue Logs.error('Fix the typo %r -> %r on %r' % (x, typos[x], ret)) return ret setattr(Build.BuildContext, m, call) def enhance_lib(): """ modify existing classes and methods """ for m in meths_typos: replace(m) # catch '..' in ant_glob patterns def ant_glob(self, *k, **kw): if k: lst=Utils.to_list(k[0]) for pat in lst: if '..' in pat.split('/'): Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'" % k[0]) if kw.get('remove', True): try: if self.is_child_of(self.ctx.bldnode) and not kw.get('quiet', False): Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)' % self) except AttributeError: pass return self.old_ant_glob(*k, **kw) Node.Node.old_ant_glob = Node.Node.ant_glob Node.Node.ant_glob = ant_glob # catch conflicting ext_in/ext_out/before/after declarations old = Task.is_before def is_before(t1, t2): ret = old(t1, t2) if ret and old(t2, t1): Logs.error('Contradictory order constraints in classes %r %r' % (t1, t2)) return ret Task.is_before = is_before # check for bld(feature='cshlib') where no 'c' is given - this can be either a mistake or on purpose # so we only issue a warning def check_err_features(self): lst = self.to_list(self.features) if 'shlib' in lst: Logs.error('feature shlib -> cshlib, dshlib or cxxshlib') for x in ('c', 'cxx', 'd', 'fc'): if not x in lst and lst and lst[0] in [x+y for y in ('program', 'shlib', 'stlib')]: Logs.error('%r features is probably missing %r' % (self, x)) TaskGen.feature('*')(check_err_features) # check for erroneous order constraints def check_err_order(self): if not hasattr(self, 'rule') and not 'subst' in Utils.to_list(self.features): for x in ('before', 'after', 'ext_in', 'ext_out'): if hasattr(self, x): Logs.warn('Erroneous order constraint %r on non-rule based task generator %r' % (x, self)) else: for x in ('before', 'after'): for y in self.to_list(getattr(self, x, [])): if not Task.classes.get(y, None): Logs.error('Erroneous order constraint %s=%r on %r (no such class)' % (x, y, self)) TaskGen.feature('*')(check_err_order) # check for @extension used with @feature/@before_method/@after_method def check_compile(self): check_invalid_constraints(self) try: ret = self.orig_compile() finally: check_same_targets(self) return ret Build.BuildContext.orig_compile = Build.BuildContext.compile Build.BuildContext.compile = check_compile # check for invalid build groups #914 def use_rec(self, name, **kw): try: y = self.bld.get_tgen_by_name(name) except Errors.WafError: pass else: idx = self.bld.get_group_idx(self) odx = self.bld.get_group_idx(y) if odx > idx: msg = "Invalid 'use' across build groups:" if Logs.verbose > 1: msg += '\n target %r\n uses:\n %r' % (self, y) else: msg += " %r uses %r (try 'waf -v -v' for the full error)" % (self.name, name) raise Errors.WafError(msg) self.orig_use_rec(name, **kw) TaskGen.task_gen.orig_use_rec = TaskGen.task_gen.use_rec TaskGen.task_gen.use_rec = use_rec # check for env.append def getattri(self, name, default=None): if name == 'append' or name == 'add': raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique') elif name == 'prepend': raise Errors.WafError('env.prepend does not exist: use env.prepend_value') if name in self.__slots__: return object.__getattr__(self, name, default) else: return self[name] ConfigSet.ConfigSet.__getattr__ = getattri def options(opt): """ Add a few methods """ enhance_lib() def configure(conf): pass 1.9.12~dfsg/waflib/Tools/ar.py0000644000000000000000000000117013214314510014657 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) """ The **ar** program creates static libraries. This tool is almost always loaded from others (C, C++, D, etc) for static library support. """ from waflib.Configure import conf @conf def find_ar(conf): """Configuration helper used by C/C++ tools to enable the support for static libraries""" conf.load('ar') def configure(conf): """Find the ar program and set the default flags in ``conf.env.ARFLAGS``""" conf.find_program('ar', var='AR') conf.add_os_flags('ARFLAGS') if not conf.env.ARFLAGS: conf.env.ARFLAGS = ['rcs'] 1.9.12~dfsg/waflib/Tools/xlc.py0000644000000000000000000000303213214314510015042 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) # Yinon Ehrlich, 2009 # Michael Kuhn, 2009 from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_xlc(conf): """ Detect the Aix C compiler """ cc = conf.find_program(['xlc_r', 'xlc'], var='CC') conf.get_xlc_version(cc) conf.env.CC_NAME = 'xlc' @conf def xlc_common_flags(conf): """ Flags required for executing the Aix C compiler """ v = conf.env v['CC_SRC_F'] = [] v['CC_TGT_F'] = ['-c', '-o'] # linker if not v['LINK_CC']: v['LINK_CC'] = v['CC'] v['CCLNK_SRC_F'] = [] v['CCLNK_TGT_F'] = ['-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-D%s' v['LIB_ST'] = '-l%s' # template for adding libs v['LIBPATH_ST'] = '-L%s' # template for adding libpaths v['STLIB_ST'] = '-l%s' v['STLIBPATH_ST'] = '-L%s' v['RPATH_ST'] = '-Wl,-rpath,%s' v['SONAME_ST'] = [] v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] # program v['LINKFLAGS_cprogram'] = ['-Wl,-brtl'] v['cprogram_PATTERN'] = '%s' # shared library v['CFLAGS_cshlib'] = ['-fPIC'] v['LINKFLAGS_cshlib'] = ['-G', '-Wl,-brtl,-bexpfull'] v['cshlib_PATTERN'] = 'lib%s.so' # static lib v['LINKFLAGS_cstlib'] = [] v['cstlib_PATTERN'] = 'lib%s.a' def configure(conf): conf.find_xlc() conf.find_ar() conf.xlc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/compiler_cxx.py0000644000000000000000000000606413214314510016760 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Matthias Jahn jahn dôt matthias ât freenet dôt de 2007 (pmarat) """ Try to detect a C++ compiler from the list of supported compilers (g++, msvc, etc):: def options(opt): opt.load('compiler_cxx') def configure(cnf): cnf.load('compiler_cxx') def build(bld): bld.program(source='main.cpp', target='app') The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_cxx.cxx_compiler`. To register a new C++ compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use:: from waflib.Tools.compiler_cxx import cxx_compiler cxx_compiler['win32'] = ['cfoo', 'msvc', 'gcc'] def options(opt): opt.load('compiler_cxx') def configure(cnf): cnf.load('compiler_cxx') def build(bld): bld.program(source='main.c', target='app') Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using:: $ CXX=clang waf configure """ import re from waflib.Tools import ccroot from waflib import Utils from waflib.Logs import debug cxx_compiler = { 'win32': ['msvc', 'g++', 'clang++'], 'cygwin': ['g++'], 'darwin': ['clang++', 'g++'], 'aix': ['xlc++', 'g++', 'clang++'], 'linux': ['g++', 'clang++', 'icpc'], 'sunos': ['sunc++', 'g++'], 'irix': ['g++'], 'hpux': ['g++'], 'osf1V': ['g++'], 'gnu': ['g++', 'clang++'], 'java': ['g++', 'msvc', 'clang++', 'icpc'], 'default': ['g++', 'clang++'] } """ Dict mapping the platform names to Waf tools finding specific C++ compilers:: from waflib.Tools.compiler_cxx import cxx_compiler cxx_compiler['linux'] = ['gxx', 'icpc', 'suncxx'] """ def default_compilers(): build_platform = Utils.unversioned_sys_platform() possible_compiler_list = cxx_compiler.get(build_platform, cxx_compiler['default']) return ' '.join(possible_compiler_list) def configure(conf): """ Try to find a suitable C++ compiler or raise a :py:class:`waflib.Errors.ConfigurationError`. """ try: test_for_compiler = conf.options.check_cxx_compiler or default_compilers() except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_cxx')") for compiler in re.split('[ ,]+', test_for_compiler): conf.env.stash() conf.start_msg('Checking for %r (C++ compiler)' % compiler) try: conf.load(compiler) except conf.errors.ConfigurationError as e: conf.env.revert() conf.end_msg(False) debug('compiler_cxx: %r' % e) else: if conf.env['CXX']: conf.end_msg(conf.env.get_flat('CXX')) conf.env['COMPILER_CXX'] = compiler break conf.end_msg(False) else: conf.fatal('could not configure a C++ compiler!') def options(opt): """ Restrict the compiler detection from the command-line:: $ waf configure --check-cxx-compiler=gxx """ test_for_compiler = default_compilers() opt.load_special_tools('cxx_*.py') cxx_compiler_opts = opt.add_option_group('Configuration options') cxx_compiler_opts.add_option('--check-cxx-compiler', default=None, help='list of C++ compilers to try [%s]' % test_for_compiler, dest="check_cxx_compiler") for x in test_for_compiler.split(): opt.load('%s' % x) 1.9.12~dfsg/waflib/Tools/c_aliases.py0000644000000000000000000000623413214314510016206 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2015 (ita) "base for all c/c++ programs and libraries" from waflib import Utils, Errors from waflib.Configure import conf def get_extensions(lst): """ :param lst: files to process :list lst: list of string or :py:class:`waflib.Node.Node` :return: list of file extensions :rtype: list of string """ ret = [] for x in Utils.to_list(lst): try: if not isinstance(x, str): x = x.name ret.append(x[x.rfind('.') + 1:]) except Exception: pass return ret def sniff_features(**kw): """ Look at the source files and return the features for a task generator (mainly cc and cxx):: snif_features(source=['foo.c', 'foo.cxx'], type='shlib') # returns ['cxx', 'c', 'cxxshlib', 'cshlib'] :param source: source files to process :type source: list of string or :py:class:`waflib.Node.Node` :param type: object type in *program*, *shlib* or *stlib* :type type: string :return: the list of features for a task generator processing the source files :rtype: list of string """ exts = get_extensions(kw['source']) type = kw['_type'] feats = [] # watch the order, cxx will have the precedence for x in 'cxx cpp c++ cc C'.split(): if x in exts: feats.append('cxx') break if 'c' in exts or 'vala' in exts or 'gs' in exts: feats.append('c') for x in 'f f90 F F90 for FOR'.split(): if x in exts: feats.append('fc') break if 'd' in exts: feats.append('d') if 'java' in exts: feats.append('java') return 'java' if type in ('program', 'shlib', 'stlib'): will_link = False for x in feats: if x in ('cxx', 'd', 'fc', 'c'): feats.append(x + type) will_link = True if not will_link and not kw.get('features', []): raise Errors.WafError('Cannot link from %r, try passing eg: features="c cprogram"?' % kw) return feats def set_features(kw, _type): kw['_type'] = _type kw['features'] = Utils.to_list(kw.get('features', [])) + Utils.to_list(sniff_features(**kw)) @conf def program(bld, *k, **kw): """ Alias for creating programs by looking at the file extensions:: def build(bld): bld.program(source='foo.c', target='app') # equivalent to: # bld(features='c cprogram', source='foo.c', target='app') """ set_features(kw, 'program') return bld(*k, **kw) @conf def shlib(bld, *k, **kw): """ Alias for creating shared libraries by looking at the file extensions:: def build(bld): bld.shlib(source='foo.c', target='app') # equivalent to: # bld(features='c cshlib', source='foo.c', target='app') """ set_features(kw, 'shlib') return bld(*k, **kw) @conf def stlib(bld, *k, **kw): """ Alias for creating static libraries by looking at the file extensions:: def build(bld): bld.stlib(source='foo.cpp', target='app') # equivalent to: # bld(features='cxx cxxstlib', source='foo.cpp', target='app') """ set_features(kw, 'stlib') return bld(*k, **kw) @conf def objects(bld, *k, **kw): """ Alias for creating object files by looking at the file extensions:: def build(bld): bld.objects(source='foo.c', target='app') # equivalent to: # bld(features='c', source='foo.c', target='app') """ set_features(kw, 'objects') return bld(*k, **kw) 1.9.12~dfsg/waflib/Tools/irixcc.py0000644000000000000000000000255513214314510015546 0ustar rootroot#! /usr/bin/env python # imported from samba """ compiler definition for irix/MIPSpro cc compiler based on suncc.py from waf """ from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_irixcc(conf): v = conf.env cc = None if v['CC']: cc = v['CC'] elif 'CC' in conf.environ: cc = conf.environ['CC'] if not cc: cc = conf.find_program('cc', var='CC') if not cc: conf.fatal('irixcc was not found') try: conf.cmd_and_log(cc + ['-version']) except Exception: conf.fatal('%r -version could not be executed' % cc) v['CC'] = cc v['CC_NAME'] = 'irix' @conf def irixcc_common_flags(conf): v = conf.env v['CC_SRC_F'] = '' v['CC_TGT_F'] = ['-c', '-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-D%s' # linker if not v['LINK_CC']: v['LINK_CC'] = v['CC'] v['CCLNK_SRC_F'] = '' v['CCLNK_TGT_F'] = ['-o'] v['LIB_ST'] = '-l%s' # template for adding libs v['LIBPATH_ST'] = '-L%s' # template for adding libpaths v['STLIB_ST'] = '-l%s' v['STLIBPATH_ST'] = '-L%s' v['cprogram_PATTERN'] = '%s' v['cshlib_PATTERN'] = 'lib%s.so' v['cstlib_PATTERN'] = 'lib%s.a' def configure(conf): conf.find_irixcc() conf.find_cpp() conf.find_ar() conf.irixcc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/clang.py0000644000000000000000000000115513214314510015344 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Krzysztof KosiÅ„ski 2014 """ Detect the Clang C compiler """ from waflib.Tools import ccroot, ar, gcc from waflib.Configure import conf @conf def find_clang(conf): """ Find the program clang and execute it to ensure it really is clang """ cc = conf.find_program('clang', var='CC') conf.get_cc_version(cc, clang=True) conf.env.CC_NAME = 'clang' def configure(conf): conf.find_clang() conf.find_program(['llvm-ar', 'ar'], var='AR') conf.find_ar() conf.gcc_common_flags() conf.gcc_modifier_platform() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/__init__.py0000644000000000000000000000010713214314510016013 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) 1.9.12~dfsg/waflib/Tools/suncxx.py0000644000000000000000000000306213214314510015607 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_sxx(conf): """ Detect the sun C++ compiler """ v = conf.env cc = conf.find_program(['CC', 'c++'], var='CXX') try: conf.cmd_and_log(cc + ['-flags']) except Exception: conf.fatal('%r is not a Sun compiler' % cc) v.CXX_NAME = 'sun' conf.get_suncc_version(cc) @conf def sxx_common_flags(conf): """ Flags required for executing the sun C++ compiler """ v = conf.env v['CXX_SRC_F'] = [] v['CXX_TGT_F'] = ['-c', '-o'] # linker if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX'] v['CXXLNK_SRC_F'] = [] v['CXXLNK_TGT_F'] = ['-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-D%s' v['LIB_ST'] = '-l%s' # template for adding libs v['LIBPATH_ST'] = '-L%s' # template for adding libpaths v['STLIB_ST'] = '-l%s' v['STLIBPATH_ST'] = '-L%s' v['SONAME_ST'] = '-Wl,-h,%s' v['SHLIB_MARKER'] = '-Bdynamic' v['STLIB_MARKER'] = '-Bstatic' # program v['cxxprogram_PATTERN'] = '%s' # shared library v['CXXFLAGS_cxxshlib'] = ['-xcode=pic32', '-DPIC'] v['LINKFLAGS_cxxshlib'] = ['-G'] v['cxxshlib_PATTERN'] = 'lib%s.so' # static lib v['LINKFLAGS_cxxstlib'] = ['-Bstatic'] v['cxxstlib_PATTERN'] = 'lib%s.a' def configure(conf): conf.find_sxx() conf.find_ar() conf.sxx_common_flags() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/icc.py0000644000000000000000000000126413214314510015017 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Stian Selnes 2008 # Thomas Nagy 2009-2010 (ita) """ Detect the Intel C compiler """ import sys from waflib.Tools import ccroot, ar, gcc from waflib.Configure import conf @conf def find_icc(conf): """ Find the program icc and execute it to ensure it really is icc """ if sys.platform == 'cygwin': conf.fatal('The Intel compiler does not work on Cygwin') cc = conf.find_program(['icc', 'ICL'], var='CC') conf.get_cc_version(cc, icc=True) conf.env.CC_NAME = 'icc' def configure(conf): conf.find_icc() conf.find_ar() conf.gcc_common_flags() conf.gcc_modifier_platform() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/xlcxx.py0000644000000000000000000000306513214314510015430 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) # Yinon Ehrlich, 2009 # Michael Kuhn, 2009 from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_xlcxx(conf): """ Detect the Aix C++ compiler """ cxx = conf.find_program(['xlc++_r', 'xlc++'], var='CXX') conf.get_xlc_version(cxx) conf.env.CXX_NAME = 'xlc++' @conf def xlcxx_common_flags(conf): """ Flags required for executing the Aix C++ compiler """ v = conf.env v['CXX_SRC_F'] = [] v['CXX_TGT_F'] = ['-c', '-o'] # linker if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX'] v['CXXLNK_SRC_F'] = [] v['CXXLNK_TGT_F'] = ['-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-D%s' v['LIB_ST'] = '-l%s' # template for adding libs v['LIBPATH_ST'] = '-L%s' # template for adding libpaths v['STLIB_ST'] = '-l%s' v['STLIBPATH_ST'] = '-L%s' v['RPATH_ST'] = '-Wl,-rpath,%s' v['SONAME_ST'] = [] v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] # program v['LINKFLAGS_cxxprogram']= ['-Wl,-brtl'] v['cxxprogram_PATTERN'] = '%s' # shared library v['CXXFLAGS_cxxshlib'] = ['-fPIC'] v['LINKFLAGS_cxxshlib'] = ['-G', '-Wl,-brtl,-bexpfull'] v['cxxshlib_PATTERN'] = 'lib%s.so' # static lib v['LINKFLAGS_cxxstlib'] = [] v['cxxstlib_PATTERN'] = 'lib%s.a' def configure(conf): conf.find_xlcxx() conf.find_ar() conf.xlcxx_common_flags() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/ccroot.py0000644000000000000000000005654513214314510015566 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ Classes and methods shared by tools providing support for C-like language such as C/C++/D/Assembly/Go (this support module is almost never used alone). """ import os, re from waflib import Task, Utils, Node, Errors from waflib.TaskGen import after_method, before_method, feature, taskgen_method, extension from waflib.Tools import c_aliases, c_preproc, c_config, c_osx, c_tests from waflib.Configure import conf SYSTEM_LIB_PATHS = ['/usr/lib64', '/usr/lib', '/usr/local/lib64', '/usr/local/lib'] USELIB_VARS = Utils.defaultdict(set) """ Mapping for features to :py:class:`waflib.ConfigSet.ConfigSet` variables. See :py:func:`waflib.Tools.ccroot.propagate_uselib_vars`. """ USELIB_VARS['c'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CCDEPS', 'CFLAGS', 'ARCH']) USELIB_VARS['cxx'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CXXDEPS', 'CXXFLAGS', 'ARCH']) USELIB_VARS['d'] = set(['INCLUDES', 'DFLAGS']) USELIB_VARS['includes'] = set(['INCLUDES', 'FRAMEWORKPATH', 'ARCH']) USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) USELIB_VARS['cstlib'] = USELIB_VARS['cxxstlib'] = set(['ARFLAGS', 'LINKDEPS']) USELIB_VARS['dprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) USELIB_VARS['dshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) USELIB_VARS['dstlib'] = set(['ARFLAGS', 'LINKDEPS']) USELIB_VARS['asm'] = set(['ASFLAGS']) # ================================================================================================= @taskgen_method def create_compiled_task(self, name, node): """ Create the compilation task: c, cxx, asm, etc. The output node is created automatically (object file with a typical **.o** extension). The task is appended to the list *compiled_tasks* which is then used by :py:func:`waflib.Tools.ccroot.apply_link` :param name: name of the task class :type name: string :param node: the file to compile :type node: :py:class:`waflib.Node.Node` :return: The task created :rtype: :py:class:`waflib.Task.Task` """ out = '%s.%d.o' % (node.name, self.idx) task = self.create_task(name, node, node.parent.find_or_declare(out)) try: self.compiled_tasks.append(task) except AttributeError: self.compiled_tasks = [task] return task @taskgen_method def to_incnodes(self, inlst): """ Task generator method provided to convert a list of string/nodes into a list of includes folders. The paths are assumed to be relative to the task generator path, except if they begin by **#** in which case they are searched from the top-level directory (``bld.srcnode``). The folders are simply assumed to be existing. The node objects in the list are returned in the output list. The strings are converted into node objects if possible. The node is searched from the source directory, and if a match is found, the equivalent build directory is created and added to the returned list too. When a folder cannot be found, it is ignored. :param inlst: list of folders :type inlst: space-delimited string or a list of string/nodes :rtype: list of :py:class:`waflib.Node.Node` :return: list of include folders as nodes """ lst = [] seen = set([]) for x in self.to_list(inlst): if x in seen or not x: continue seen.add(x) # with a real lot of targets, it is sometimes interesting to cache the results below if isinstance(x, Node.Node): lst.append(x) else: if os.path.isabs(x): lst.append(self.bld.root.make_node(x) or x) else: if x[0] == '#': p = self.bld.bldnode.make_node(x[1:]) v = self.bld.srcnode.make_node(x[1:]) else: p = self.path.get_bld().make_node(x) v = self.path.make_node(x) if p.is_child_of(self.bld.bldnode): p.mkdir() lst.append(p) lst.append(v) return lst @feature('c', 'cxx', 'd', 'asm', 'fc', 'includes') @after_method('propagate_uselib_vars', 'process_source') def apply_incpaths(self): """ Task generator method that processes the attribute *includes*:: tg = bld(features='includes', includes='.') The folders only need to be relative to the current directory, the equivalent build directory is added automatically (for headers created in the build directory). This enable using a build directory or not (``top == out``). This method will add a list of nodes read by :py:func:`waflib.Tools.ccroot.to_incnodes` in ``tg.env.INCPATHS``, and the list of include paths in ``tg.env.INCLUDES``. """ lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) self.includes_nodes = lst self.env['INCPATHS'] = [x.abspath() for x in lst] class link_task(Task.Task): """ Base class for all link tasks. A task generator is supposed to have at most one link task bound in the attribute *link_task*. See :py:func:`waflib.Tools.ccroot.apply_link`. .. inheritance-diagram:: waflib.Tools.ccroot.stlink_task waflib.Tools.c.cprogram waflib.Tools.c.cshlib waflib.Tools.cxx.cxxstlib waflib.Tools.cxx.cxxprogram waflib.Tools.cxx.cxxshlib waflib.Tools.d.dprogram waflib.Tools.d.dshlib waflib.Tools.d.dstlib waflib.Tools.ccroot.fake_shlib waflib.Tools.ccroot.fake_stlib waflib.Tools.asm.asmprogram waflib.Tools.asm.asmshlib waflib.Tools.asm.asmstlib """ color = 'YELLOW' inst_to = None """Default installation path for the link task outputs, or None to disable""" chmod = Utils.O755 """Default installation mode for the link task outputs""" def add_target(self, target): """ Process the *target* attribute to add the platform-specific prefix/suffix such as *.so* or *.exe*. The settings are retrieved from ``env.clsname_PATTERN`` """ if isinstance(target, str): pattern = self.env[self.__class__.__name__ + '_PATTERN'] if not pattern: pattern = '%s' folder, name = os.path.split(target) if self.__class__.__name__.find('shlib') > 0 and getattr(self.generator, 'vnum', None): nums = self.generator.vnum.split('.') if self.env.DEST_BINFMT == 'pe': # include the version in the dll file name, # the import lib file name stays unversionned. name = name + '-' + nums[0] elif self.env.DEST_OS == 'openbsd': pattern = '%s.%s' % (pattern, nums[0]) if len(nums) >= 2: pattern += '.%s' % nums[1] if folder: tmp = folder + os.sep + pattern % name else: tmp = pattern % name target = self.generator.path.find_or_declare(tmp) self.set_outputs(target) class stlink_task(link_task): """ Base for static link tasks, which use *ar* most of the time. The target is always removed before being written. """ run_str = '${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}' chmod = Utils.O644 """Default installation mode for the static libraries""" def rm_tgt(cls): old = cls.run def wrap(self): try: os.remove(self.outputs[0].abspath()) except OSError: pass return old(self) setattr(cls, 'run', wrap) rm_tgt(stlink_task) @feature('c', 'cxx', 'd', 'fc', 'asm') @after_method('process_source') def apply_link(self): """ Collect the tasks stored in ``compiled_tasks`` (created by :py:func:`waflib.Tools.ccroot.create_compiled_task`), and use the outputs for a new instance of :py:class:`waflib.Tools.ccroot.link_task`. The class to use is the first link task matching a name from the attribute *features*, for example:: def build(bld): tg = bld(features='cxx cxxprogram cprogram', source='main.c', target='app') will create the task ``tg.link_task`` as a new instance of :py:class:`waflib.Tools.cxx.cxxprogram` """ for x in self.features: if x == 'cprogram' and 'cxx' in self.features: # limited compat x = 'cxxprogram' elif x == 'cshlib' and 'cxx' in self.features: x = 'cxxshlib' if x in Task.classes: if issubclass(Task.classes[x], link_task): link = x break else: return objs = [t.outputs[0] for t in getattr(self, 'compiled_tasks', [])] self.link_task = self.create_task(link, objs) self.link_task.add_target(self.target) # remember that the install paths are given by the task generators try: inst_to = self.install_path except AttributeError: inst_to = self.link_task.__class__.inst_to if inst_to: # install a copy of the node list we have at this moment (implib not added) self.install_task = self.bld.install_files(inst_to, self.link_task.outputs[:], env=self.env, chmod=self.link_task.chmod, task=self.link_task) @taskgen_method def use_rec(self, name, **kw): """ Processes the ``use`` keyword recursively. This method is kind of private and only meant to be used from ``process_use`` """ if name in self.tmp_use_not or name in self.tmp_use_seen: return try: y = self.bld.get_tgen_by_name(name) except Errors.WafError: self.uselib.append(name) self.tmp_use_not.add(name) return self.tmp_use_seen.append(name) y.post() # bind temporary attributes on the task generator y.tmp_use_objects = objects = kw.get('objects', True) y.tmp_use_stlib = stlib = kw.get('stlib', True) try: link_task = y.link_task except AttributeError: y.tmp_use_var = '' else: objects = False if not isinstance(link_task, stlink_task): stlib = False y.tmp_use_var = 'LIB' else: y.tmp_use_var = 'STLIB' p = self.tmp_use_prec for x in self.to_list(getattr(y, 'use', [])): if self.env["STLIB_" + x]: continue try: p[x].append(name) except KeyError: p[x] = [name] self.use_rec(x, objects=objects, stlib=stlib) @feature('c', 'cxx', 'd', 'use', 'fc') @before_method('apply_incpaths', 'propagate_uselib_vars') @after_method('apply_link', 'process_source') def process_use(self): """ Process the ``use`` attribute which contains a list of task generator names:: def build(bld): bld.shlib(source='a.c', target='lib1') bld.program(source='main.c', target='app', use='lib1') See :py:func:`waflib.Tools.ccroot.use_rec`. """ use_not = self.tmp_use_not = set([]) self.tmp_use_seen = [] # we would like an ordered set use_prec = self.tmp_use_prec = {} self.uselib = self.to_list(getattr(self, 'uselib', [])) self.includes = self.to_list(getattr(self, 'includes', [])) names = self.to_list(getattr(self, 'use', [])) for x in names: self.use_rec(x) for x in use_not: if x in use_prec: del use_prec[x] # topological sort out = [] tmp = [] for x in self.tmp_use_seen: for k in use_prec.values(): if x in k: break else: tmp.append(x) while tmp: e = tmp.pop() out.append(e) try: nlst = use_prec[e] except KeyError: pass else: del use_prec[e] for x in nlst: for y in use_prec: if x in use_prec[y]: break else: tmp.append(x) if use_prec: raise Errors.WafError('Cycle detected in the use processing %r' % use_prec) out.reverse() link_task = getattr(self, 'link_task', None) for x in out: y = self.bld.get_tgen_by_name(x) var = y.tmp_use_var if var and link_task: if var == 'LIB' or y.tmp_use_stlib or x in names: self.env.append_value(var, [y.target[y.target.rfind(os.sep) + 1:]]) self.link_task.dep_nodes.extend(y.link_task.outputs) tmp_path = y.link_task.outputs[0].parent.path_from(self.bld.bldnode) self.env.append_unique(var + 'PATH', [tmp_path]) else: if y.tmp_use_objects: self.add_objects_from_tgen(y) if getattr(y, 'export_includes', None): self.includes.extend(y.to_incnodes(y.export_includes)) if getattr(y, 'export_defines', None): self.env.append_value('DEFINES', self.to_list(y.export_defines)) # and finally, add the use variables (no recursion needed) for x in names: try: y = self.bld.get_tgen_by_name(x) except Errors.WafError: if not self.env['STLIB_' + x] and not x in self.uselib: self.uselib.append(x) else: for k in self.to_list(getattr(y, 'use', [])): if not self.env['STLIB_' + k] and not k in self.uselib: self.uselib.append(k) @taskgen_method def accept_node_to_link(self, node): """ PRIVATE INTERNAL USE ONLY """ return not node.name.endswith('.pdb') @taskgen_method def add_objects_from_tgen(self, tg): """ Add the objects from the depending compiled tasks as link task inputs. Some objects are filtered: for instance, .pdb files are added to the compiled tasks but not to the link tasks (to avoid errors) PRIVATE INTERNAL USE ONLY """ try: link_task = self.link_task except AttributeError: pass else: for tsk in getattr(tg, 'compiled_tasks', []): for x in tsk.outputs: if self.accept_node_to_link(x): link_task.inputs.append(x) @taskgen_method def get_uselib_vars(self): """ :return: the *uselib* variables associated to the *features* attribute (see :py:attr:`waflib.Tools.ccroot.USELIB_VARS`) :rtype: list of string """ _vars = set([]) for x in self.features: if x in USELIB_VARS: _vars |= USELIB_VARS[x] return _vars @feature('c', 'cxx', 'd', 'fc', 'javac', 'cs', 'uselib', 'asm') @after_method('process_use') def propagate_uselib_vars(self): """ Process uselib variables for adding flags. For example, the following target:: def build(bld): bld.env.AFLAGS_aaa = ['bar'] from waflib.Tools.ccroot import USELIB_VARS USELIB_VARS['aaa'] = set('AFLAGS') tg = bld(features='aaa', aflags='test') The *aflags* attribute will be processed and this method will set:: tg.env.AFLAGS = ['bar', 'test'] """ _vars = self.get_uselib_vars() env = self.env app = env.append_value feature_uselib = self.features + self.to_list(getattr(self, 'uselib', [])) for var in _vars: y = var.lower() val = getattr(self, y, []) if val: app(var, self.to_list(val)) for x in feature_uselib: val = env['%s_%s' % (var, x)] if val: app(var, val) # ============ the code above must not know anything about import libs ========== @feature('cshlib', 'cxxshlib', 'fcshlib') @after_method('apply_link') def apply_implib(self): """ Handle dlls and their import libs on Windows-like systems. A ``.dll.a`` file called *import library* is generated. It must be installed as it is required for linking the library. """ if not self.env.DEST_BINFMT == 'pe': return dll = self.link_task.outputs[0] if isinstance(self.target, Node.Node): name = self.target.name else: name = os.path.split(self.target)[1] implib = self.env['implib_PATTERN'] % name implib = dll.parent.find_or_declare(implib) self.env.append_value('LINKFLAGS', self.env['IMPLIB_ST'] % implib.bldpath()) self.link_task.outputs.append(implib) if getattr(self, 'defs', None) and self.env.DEST_BINFMT == 'pe': node = self.path.find_resource(self.defs) if not node: raise Errors.WafError('invalid def file %r' % self.defs) if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME): self.env.append_value('LINKFLAGS', '/def:%s' % node.path_from(self.bld.bldnode)) self.link_task.dep_nodes.append(node) else: #gcc for windows takes *.def file a an input without any special flag self.link_task.inputs.append(node) # where to put the import library if getattr(self, 'install_task', None): try: # user has given a specific installation path for the import library inst_to = self.install_path_implib except AttributeError: try: # user has given an installation path for the main library, put the import library in it inst_to = self.install_path except AttributeError: # else, put the library in BINDIR and the import library in LIBDIR inst_to = '${IMPLIBDIR}' self.install_task.dest = '${BINDIR}' if not self.env.IMPLIBDIR: self.env.IMPLIBDIR = self.env.LIBDIR self.implib_install_task = self.bld.install_files(inst_to, implib, env=self.env, chmod=self.link_task.chmod, task=self.link_task) # ============ the code above must not know anything about vnum processing on unix platforms ========= re_vnum = re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$') @feature('cshlib', 'cxxshlib', 'dshlib', 'fcshlib', 'vnum') @after_method('apply_link', 'propagate_uselib_vars') def apply_vnum(self): """ Enforce version numbering on shared libraries. The valid version numbers must have either zero or two dots:: def build(bld): bld.shlib(source='a.c', target='foo', vnum='14.15.16') In this example on Linux platform, ``libfoo.so`` is installed as ``libfoo.so.14.15.16``, and the following symbolic links are created: * ``libfoo.so → libfoo.so.14.15.16`` * ``libfoo.so.14 → libfoo.so.14.15.16`` By default, the library will be assigned SONAME ``libfoo.so.14``, effectively declaring ABI compatibility between all minor and patch releases for the major version of the library. When necessary, the compatibility can be explicitly defined using `cnum` parameter: def build(bld): bld.shlib(source='a.c', target='foo', vnum='14.15.16', cnum='14.15') In this case, the assigned SONAME will be ``libfoo.so.14.15`` with ABI compatibility only between path releases for a specific major and minor version of the library. On OS X platform, install-name parameter will follow the above logic for SONAME with exception that it also specifies an absolute path (based on install_path) of the library. """ if not getattr(self, 'vnum', '') or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'): return link = self.link_task if not re_vnum.match(self.vnum): raise Errors.WafError('Invalid vnum %r for target %r' % (self.vnum, getattr(self, 'name', self))) nums = self.vnum.split('.') node = link.outputs[0] cnum = getattr(self, 'cnum', str(nums[0])) cnums = cnum.split('.') if len(cnums)>len(nums) or nums[0:len(cnums)] != cnums: raise Errors.WafError('invalid compatibility version %s' % cnum) libname = node.name if libname.endswith('.dylib'): name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum) name2 = libname.replace('.dylib', '.%s.dylib' % cnum) else: name3 = libname + '.' + self.vnum name2 = libname + '.' + cnum # add the so name for the ld linker - to disable, just unset env.SONAME_ST if self.env.SONAME_ST: v = self.env.SONAME_ST % name2 self.env.append_value('LINKFLAGS', v.split()) # the following task is just to enable execution from the build dir :-/ if self.env.DEST_OS != 'openbsd': outs = [node.parent.find_or_declare(name3)] if name2 != name3: outs.append(node.parent.find_or_declare(name2)) self.create_task('vnum', node, outs) if getattr(self, 'install_task', None): self.install_task.hasrun = Task.SKIP_ME bld = self.bld path = self.install_task.dest if self.env.DEST_OS == 'openbsd': libname = self.link_task.outputs[0].name t1 = bld.install_as('%s%s%s' % (path, os.sep, libname), node, env=self.env, chmod=self.link_task.chmod) self.vnum_install_task = (t1,) else: t1 = bld.install_as(path + os.sep + name3, node, env=self.env, chmod=self.link_task.chmod) t3 = bld.symlink_as(path + os.sep + libname, name3) if name2 != name3: t2 = bld.symlink_as(path + os.sep + name2, name3) self.vnum_install_task = (t1, t2, t3) else: self.vnum_install_task = (t1, t3) if '-dynamiclib' in self.env['LINKFLAGS']: # this requires after(propagate_uselib_vars) try: inst_to = self.install_path except AttributeError: inst_to = self.link_task.__class__.inst_to if inst_to: p = Utils.subst_vars(inst_to, self.env) path = os.path.join(p, name2) self.env.append_value('LINKFLAGS', ['-install_name', path]) self.env.append_value('LINKFLAGS', '-Wl,-compatibility_version,%s' % cnum) self.env.append_value('LINKFLAGS', '-Wl,-current_version,%s' % self.vnum) class vnum(Task.Task): """ Create the symbolic links for a versioned shared library. Instances are created by :py:func:`waflib.Tools.ccroot.apply_vnum` """ color = 'CYAN' quient = True ext_in = ['.bin'] def keyword(self): return 'Symlinking' def run(self): for x in self.outputs: path = x.abspath() try: os.remove(path) except OSError: pass try: os.symlink(self.inputs[0].name, path) except OSError: return 1 class fake_shlib(link_task): """ Task used for reading a system library and adding the dependency on it """ def runnable_status(self): for t in self.run_after: if not t.hasrun: return Task.ASK_LATER for x in self.outputs: x.sig = Utils.h_file(x.abspath()) return Task.SKIP_ME class fake_stlib(stlink_task): """ Task used for reading a system library and adding the dependency on it """ def runnable_status(self): for t in self.run_after: if not t.hasrun: return Task.ASK_LATER for x in self.outputs: x.sig = Utils.h_file(x.abspath()) return Task.SKIP_ME @conf def read_shlib(self, name, paths=[], export_includes=[], export_defines=[]): """ Read a system shared library, enabling its use as a local library. Will trigger a rebuild if the file changes:: def build(bld): bld.read_shlib('m') bld.program(source='main.c', use='m') """ return self(name=name, features='fake_lib', lib_paths=paths, lib_type='shlib', export_includes=export_includes, export_defines=export_defines) @conf def read_stlib(self, name, paths=[], export_includes=[], export_defines=[]): """ Read a system static library, enabling a use as a local library. Will trigger a rebuild if the file changes. """ return self(name=name, features='fake_lib', lib_paths=paths, lib_type='stlib', export_includes=export_includes, export_defines=export_defines) lib_patterns = { 'shlib' : ['lib%s.so', '%s.so', 'lib%s.dylib', 'lib%s.dll', '%s.dll'], 'stlib' : ['lib%s.a', '%s.a', 'lib%s.dll', '%s.dll', 'lib%s.lib', '%s.lib'], } @feature('fake_lib') def process_lib(self): """ Find the location of a foreign library. Used by :py:class:`waflib.Tools.ccroot.read_shlib` and :py:class:`waflib.Tools.ccroot.read_stlib`. """ node = None names = [x % self.name for x in lib_patterns[self.lib_type]] for x in self.lib_paths + [self.path] + SYSTEM_LIB_PATHS: if not isinstance(x, Node.Node): x = self.bld.root.find_node(x) or self.path.find_node(x) if not x: continue for y in names: node = x.find_node(y) if node: node.sig = Utils.h_file(node.abspath()) break else: continue break else: raise Errors.WafError('could not find library %r' % self.name) self.link_task = self.create_task('fake_%s' % self.lib_type, [], [node]) self.target = self.name class fake_o(Task.Task): def runnable_status(self): return Task.SKIP_ME @extension('.o', '.obj') def add_those_o_files(self, node): tsk = self.create_task('fake_o', [], node) try: self.compiled_tasks.append(tsk) except AttributeError: self.compiled_tasks = [tsk] @feature('fake_obj') @before_method('process_source') def process_objs(self): """ Puts object files in the task generator outputs """ for node in self.to_nodes(self.source): self.add_those_o_files(node) self.source = [] @conf def read_object(self, obj): """ Read an object file, enabling injection in libs/programs. Will trigger a rebuild if the file changes. :param obj: object file path, as string or Node """ if not isinstance(obj, self.path.__class__): obj = self.path.find_resource(obj) return self(features='fake_obj', source=obj, name=obj.name) @feature('cxxprogram', 'cprogram') @after_method('apply_link', 'process_use') def set_full_paths_hpux(self): """ On hp-ux, extend the libpaths and static library paths to absolute paths """ if self.env.DEST_OS != 'hp-ux': return base = self.bld.bldnode.abspath() for var in ['LIBPATH', 'STLIBPATH']: lst = [] for x in self.env[var]: if x.startswith('/'): lst.append(x) else: lst.append(os.path.normpath(os.path.join(base, x))) self.env[var] = lst 1.9.12~dfsg/waflib/Tools/c_preproc.py0000644000000000000000000006620113214314510016237 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) """ C/C++ preprocessor for finding dependencies Reasons for using the Waf preprocessor by default #. Some c/c++ extensions (Qt) require a custom preprocessor for obtaining the dependencies (.moc files) #. Not all compilers provide .d files for obtaining the dependencies (portability) #. A naive file scanner will not catch the constructs such as "#include foo()" #. A naive file scanner will catch unnecessary dependencies (change an unused header -> recompile everything) Regarding the speed concerns: * the preprocessing is performed only when files must be compiled * the macros are evaluated only for #if/#elif/#include * system headers are not scanned by default Now if you do not want the Waf preprocessor, the tool +gccdeps* uses the .d files produced during the compilation to track the dependencies (useful when used with the boost libraries). It only works with gcc >= 4.4 though. A dumb preprocessor is also available in the tool *c_dumbpreproc* """ # TODO: more varargs, pragma once import re, string, traceback from waflib import Logs, Utils, Errors from waflib.Logs import debug, error class PreprocError(Errors.WafError): pass POPFILE = '-' "Constant representing a special token used in :py:meth:`waflib.Tools.c_preproc.c_parser.start` iteration to switch to a header read previously" recursion_limit = 150 "Limit on the amount of files to read in the dependency scanner" go_absolute = False "Set to True to track headers on files in /usr/include, else absolute paths are ignored (but it becomes very slow)" standard_includes = ['/usr/include'] if Utils.is_win32: standard_includes = [] use_trigraphs = 0 """Apply trigraph rules (False by default)""" strict_quotes = 0 """Reserve the "#include <>" quotes for system includes (do not search for those includes). False by default.""" g_optrans = { 'not':'!', 'not_eq':'!', 'and':'&&', 'and_eq':'&=', 'or':'||', 'or_eq':'|=', 'xor':'^', 'xor_eq':'^=', 'bitand':'&', 'bitor':'|', 'compl':'~', } """Operators such as and/or/xor for c++. Set an empty dict to disable.""" # ignore #warning and #error re_lines = re.compile( '^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$', re.IGNORECASE | re.MULTILINE) """Match #include lines""" re_mac = re.compile("^[a-zA-Z_]\w*") """Match macro definitions""" re_fun = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]') """Match macro functions""" re_pragma_once = re.compile('^\s*once\s*', re.IGNORECASE) """Match #pragma once statements""" re_nl = re.compile('\\\\\r*\n', re.MULTILINE) """Match newlines""" re_cpp = re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE ) """Filter C/C++ comments""" trig_def = [('??'+a, b) for a, b in zip("=-/!'()<>", r'#~\|^[]{}')] """Trigraph definitions""" chr_esc = {'0':0, 'a':7, 'b':8, 't':9, 'n':10, 'f':11, 'v':12, 'r':13, '\\':92, "'":39} """Escape characters""" NUM = 'i' """Number token""" OP = 'O' """Operator token""" IDENT = 'T' """Identifier token""" STR = 's' """String token""" CHAR = 'c' """Character token""" tok_types = [NUM, STR, IDENT, OP] """Token types""" exp_types = [ r"""0[xX](?P[a-fA-F0-9]+)(?P[uUlL]*)|L*?'(?P(\\.|[^\\'])+)'|(?P\d+)[Ee](?P[+-]*?\d+)(?P[fFlL]*)|(?P\d*\.\d+)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P\d+\.\d*)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P0*)(?P\d+)(?P[uUlL]*)""", r'L?"([^"\\]|\\.)*"', r'[a-zA-Z_]\w*', r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]', ] """Expression types""" re_clexer = re.compile('|'.join(["(?P<%s>%s)" % (name, part) for name, part in zip(tok_types, exp_types)]), re.M) """Match expressions into tokens""" accepted = 'a' """Parser state is *accepted*""" ignored = 'i' """Parser state is *ignored*, for example preprocessor lines in an #if 0 block""" undefined = 'u' """Parser state is *undefined* at the moment""" skipped = 's' """Parser state is *skipped*, for example preprocessor lines in a #elif 0 block""" def repl(m): """Replace function used with :py:attr:`waflib.Tools.c_preproc.re_cpp`""" s = m.group(0) if s.startswith('/'): return ' ' return s def filter_comments(filename): """ Filter the comments from a c/h file, and return the preprocessor lines. The regexps :py:attr:`waflib.Tools.c_preproc.re_cpp`, :py:attr:`waflib.Tools.c_preproc.re_nl` and :py:attr:`waflib.Tools.c_preproc.re_lines` are used internally. :return: the preprocessor directives as a list of (keyword, line) :rtype: a list of string pairs """ # return a list of tuples : keyword, line code = Utils.readf(filename) if use_trigraphs: for (a, b) in trig_def: code = code.split(a).join(b) code = re_nl.sub('', code) code = re_cpp.sub(repl, code) return [(m.group(2), m.group(3)) for m in re.finditer(re_lines, code)] prec = {} """ Operator precendence rules required for parsing expressions of the form:: #if 1 && 2 != 0 """ ops = ['* / %', '+ -', '<< >>', '< <= >= >', '== !=', '& | ^', '&& ||', ','] for x in range(len(ops)): syms = ops[x] for u in syms.split(): prec[u] = x def trimquotes(s): """ Remove the single quotes around an expression:: trimquotes("'test'") == "test" :param s: expression to transform :type s: string :rtype: string """ if not s: return '' s = s.rstrip() if s[0] == "'" and s[-1] == "'": return s[1:-1] return s def reduce_nums(val_1, val_2, val_op): """ Apply arithmetic rules to compute a result :param val1: input parameter :type val1: int or string :param val2: input parameter :type val2: int or string :param val_op: C operator in *+*, */*, *-*, etc :type val_op: string :rtype: int """ #print val_1, val_2, val_op # now perform the operation, make certain a and b are numeric try: a = 0 + val_1 except TypeError: a = int(val_1) try: b = 0 + val_2 except TypeError: b = int(val_2) d = val_op if d == '%': c = a%b elif d=='+': c = a+b elif d=='-': c = a-b elif d=='*': c = a*b elif d=='/': c = a/b elif d=='^': c = a^b elif d=='==': c = int(a == b) elif d=='|' or d == 'bitor': c = a|b elif d=='||' or d == 'or' : c = int(a or b) elif d=='&' or d == 'bitand': c = a&b elif d=='&&' or d == 'and': c = int(a and b) elif d=='!=' or d == 'not_eq': c = int(a != b) elif d=='^' or d == 'xor': c = int(a^b) elif d=='<=': c = int(a <= b) elif d=='<': c = int(a < b) elif d=='>': c = int(a > b) elif d=='>=': c = int(a >= b) elif d=='<<': c = a<>': c = a>>b else: c = 0 return c def get_num(lst): """ Try to obtain a number from a list of tokens. The token types are defined in :py:attr:`waflib.Tools.ccroot.tok_types`. :param lst: list of preprocessor tokens :type lst: list of tuple (tokentype, value) :return: a pair containing the number and the rest of the list :rtype: tuple(value, list) """ if not lst: raise PreprocError("empty list for get_num") (p, v) = lst[0] if p == OP: if v == '(': count_par = 1 i = 1 while i < len(lst): (p, v) = lst[i] if p == OP: if v == ')': count_par -= 1 if count_par == 0: break elif v == '(': count_par += 1 i += 1 else: raise PreprocError("rparen expected %r" % lst) (num, _) = get_term(lst[1:i]) return (num, lst[i+1:]) elif v == '+': return get_num(lst[1:]) elif v == '-': num, lst = get_num(lst[1:]) return (reduce_nums('-1', num, '*'), lst) elif v == '!': num, lst = get_num(lst[1:]) return (int(not int(num)), lst) elif v == '~': num, lst = get_num(lst[1:]) return (~ int(num), lst) else: raise PreprocError("Invalid op token %r for get_num" % lst) elif p == NUM: return v, lst[1:] elif p == IDENT: # all macros should have been replaced, remaining identifiers eval to 0 return 0, lst[1:] else: raise PreprocError("Invalid token %r for get_num" % lst) def get_term(lst): """ Evaluate an expression recursively, for example:: 1+1+1 -> 2+1 -> 3 :param lst: list of tokens :type lst: list of tuple(token, value) :return: the value and the remaining tokens :rtype: value, list """ if not lst: raise PreprocError("empty list for get_term") num, lst = get_num(lst) if not lst: return (num, []) (p, v) = lst[0] if p == OP: if v == ',': # skip return get_term(lst[1:]) elif v == '?': count_par = 0 i = 1 while i < len(lst): (p, v) = lst[i] if p == OP: if v == ')': count_par -= 1 elif v == '(': count_par += 1 elif v == ':': if count_par == 0: break i += 1 else: raise PreprocError("rparen expected %r" % lst) if int(num): return get_term(lst[1:i]) else: return get_term(lst[i+1:]) else: num2, lst = get_num(lst[1:]) if not lst: # no more tokens to process num2 = reduce_nums(num, num2, v) return get_term([(NUM, num2)] + lst) # operator precedence p2, v2 = lst[0] if p2 != OP: raise PreprocError("op expected %r" % lst) if prec[v2] >= prec[v]: num2 = reduce_nums(num, num2, v) return get_term([(NUM, num2)] + lst) else: num3, lst = get_num(lst[1:]) num3 = reduce_nums(num2, num3, v2) return get_term([(NUM, num), (p, v), (NUM, num3)] + lst) raise PreprocError("cannot reduce %r" % lst) def reduce_eval(lst): """ Take a list of tokens and output true or false for #if/#elif conditions. :param lst: a list of tokens :type lst: list of tuple(token, value) :return: a token :rtype: tuple(NUM, int) """ num, lst = get_term(lst) return (NUM, num) def stringize(lst): """ Merge a list of tokens into a string :param lst: a list of tokens :type lst: list of tuple(token, value) :rtype: string """ lst = [str(v2) for (p2, v2) in lst] return "".join(lst) def paste_tokens(t1, t2): """ Token pasting works between identifiers, particular operators, and identifiers and numbers:: a ## b -> ab > ## = -> >= a ## 2 -> a2 :param t1: token :type t1: tuple(type, value) :param t2: token :type t2: tuple(type, value) """ p1 = None if t1[0] == OP and t2[0] == OP: p1 = OP elif t1[0] == IDENT and (t2[0] == IDENT or t2[0] == NUM): p1 = IDENT elif t1[0] == NUM and t2[0] == NUM: p1 = NUM if not p1: raise PreprocError('tokens do not make a valid paste %r and %r' % (t1, t2)) return (p1, t1[1] + t2[1]) def reduce_tokens(lst, defs, ban=[]): """ Replace the tokens in lst, using the macros provided in defs, and a list of macros that cannot be re-applied :param lst: list of tokens :type lst: list of tuple(token, value) :param defs: macro definitions :type defs: dict :param ban: macros that cannot be substituted (recursion is not allowed) :type ban: list of string :return: the new list of tokens :rtype: value, list """ i = 0 while i < len(lst): (p, v) = lst[i] if p == IDENT and v == "defined": del lst[i] if i < len(lst): (p2, v2) = lst[i] if p2 == IDENT: if v2 in defs: lst[i] = (NUM, 1) else: lst[i] = (NUM, 0) elif p2 == OP and v2 == '(': del lst[i] (p2, v2) = lst[i] del lst[i] # remove the ident, and change the ) for the value if v2 in defs: lst[i] = (NUM, 1) else: lst[i] = (NUM, 0) else: raise PreprocError("Invalid define expression %r" % lst) elif p == IDENT and v in defs: if isinstance(defs[v], str): a, b = extract_macro(defs[v]) defs[v] = b macro_def = defs[v] to_add = macro_def[1] if isinstance(macro_def[0], list): # macro without arguments del lst[i] accu = to_add[:] reduce_tokens(accu, defs, ban+[v]) for x in range(len(accu)): lst.insert(i, accu[x]) i += 1 else: # collect the arguments for the funcall args = [] del lst[i] if i >= len(lst): raise PreprocError("expected '(' after %r (got nothing)" % v) (p2, v2) = lst[i] if p2 != OP or v2 != '(': raise PreprocError("expected '(' after %r" % v) del lst[i] one_param = [] count_paren = 0 while i < len(lst): p2, v2 = lst[i] del lst[i] if p2 == OP and count_paren == 0: if v2 == '(': one_param.append((p2, v2)) count_paren += 1 elif v2 == ')': if one_param: args.append(one_param) break elif v2 == ',': if not one_param: raise PreprocError("empty param in funcall %s" % v) args.append(one_param) one_param = [] else: one_param.append((p2, v2)) else: one_param.append((p2, v2)) if v2 == '(': count_paren += 1 elif v2 == ')': count_paren -= 1 else: raise PreprocError('malformed macro') # substitute the arguments within the define expression accu = [] arg_table = macro_def[0] j = 0 while j < len(to_add): (p2, v2) = to_add[j] if p2 == OP and v2 == '#': # stringize is for arguments only if j+1 < len(to_add) and to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table: toks = args[arg_table[to_add[j+1][1]]] accu.append((STR, stringize(toks))) j += 1 else: accu.append((p2, v2)) elif p2 == OP and v2 == '##': # token pasting, how can man invent such a complicated system? if accu and j+1 < len(to_add): # we have at least two tokens t1 = accu[-1] if to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table: toks = args[arg_table[to_add[j+1][1]]] if toks: accu[-1] = paste_tokens(t1, toks[0]) #(IDENT, accu[-1][1] + toks[0][1]) accu.extend(toks[1:]) else: # error, case "a##" accu.append((p2, v2)) accu.extend(toks) elif to_add[j+1][0] == IDENT and to_add[j+1][1] == '__VA_ARGS__': # TODO not sure # first collect the tokens va_toks = [] st = len(macro_def[0]) pt = len(args) for x in args[pt-st+1:]: va_toks.extend(x) va_toks.append((OP, ',')) if va_toks: va_toks.pop() # extra comma if len(accu)>1: (p3, v3) = accu[-1] (p4, v4) = accu[-2] if v3 == '##': # remove the token paste accu.pop() if v4 == ',' and pt < st: # remove the comma accu.pop() accu += va_toks else: accu[-1] = paste_tokens(t1, to_add[j+1]) j += 1 else: # Invalid paste, case "##a" or "b##" accu.append((p2, v2)) elif p2 == IDENT and v2 in arg_table: toks = args[arg_table[v2]] reduce_tokens(toks, defs, ban+[v]) accu.extend(toks) else: accu.append((p2, v2)) j += 1 reduce_tokens(accu, defs, ban+[v]) for x in range(len(accu)-1, -1, -1): lst.insert(i, accu[x]) i += 1 def eval_macro(lst, defs): """ Reduce the tokens by :py:func:`waflib.Tools.c_preproc.reduce_tokens` and try to return a 0/1 result by :py:func:`waflib.Tools.c_preproc.reduce_eval`. :param lst: list of tokens :type lst: list of tuple(token, value) :param defs: macro definitions :type defs: dict :rtype: int """ reduce_tokens(lst, defs, []) if not lst: raise PreprocError("missing tokens to evaluate") (p, v) = reduce_eval(lst) return int(v) != 0 def extract_macro(txt): """ Process a macro definition of the form:: #define f(x, y) x * y into a function or a simple macro without arguments :param txt: expression to exact a macro definition from :type txt: string :return: a tuple containing the name, the list of arguments and the replacement :rtype: tuple(string, [list, list]) """ t = tokenize(txt) if re_fun.search(txt): p, name = t[0] p, v = t[1] if p != OP: raise PreprocError("expected open parenthesis") i = 1 pindex = 0 params = {} prev = '(' while 1: i += 1 p, v = t[i] if prev == '(': if p == IDENT: params[v] = pindex pindex += 1 prev = p elif p == OP and v == ')': break else: raise PreprocError("unexpected token (3)") elif prev == IDENT: if p == OP and v == ',': prev = v elif p == OP and v == ')': break else: raise PreprocError("comma or ... expected") elif prev == ',': if p == IDENT: params[v] = pindex pindex += 1 prev = p elif p == OP and v == '...': raise PreprocError("not implemented (1)") else: raise PreprocError("comma or ... expected (2)") elif prev == '...': raise PreprocError("not implemented (2)") else: raise PreprocError("unexpected else") #~ print (name, [params, t[i+1:]]) return (name, [params, t[i+1:]]) else: (p, v) = t[0] if len(t) > 1: return (v, [[], t[1:]]) else: # empty define, assign an empty token return (v, [[], [('T','')]]) re_include = re.compile('^\s*(<(?P.*)>|"(?P.*)")') def extract_include(txt, defs): """ Process a line in the form:: #include foo :param txt: include line to process :type txt: string :param defs: macro definitions :type defs: dict :return: the file name :rtype: string """ m = re_include.search(txt) if m: if m.group('a'): return '<', m.group('a') if m.group('b'): return '"', m.group('b') # perform preprocessing and look at the result, it must match an include toks = tokenize(txt) reduce_tokens(toks, defs, ['waf_include']) if not toks: raise PreprocError("could not parse include %s" % txt) if len(toks) == 1: if toks[0][0] == STR: return '"', toks[0][1] else: if toks[0][1] == '<' and toks[-1][1] == '>': ret = '<', stringize(toks).lstrip('<').rstrip('>') return ret raise PreprocError("could not parse include %s." % txt) def parse_char(txt): """ Parse a c character :param txt: character to parse :type txt: string :return: a character literal :rtype: string """ if not txt: raise PreprocError("attempted to parse a null char") if txt[0] != '\\': return ord(txt) c = txt[1] if c == 'x': if len(txt) == 4 and txt[3] in string.hexdigits: return int(txt[2:], 16) return int(txt[2:], 16) elif c.isdigit(): if c == '0' and len(txt)==2: return 0 for i in 3, 2, 1: if len(txt) > i and txt[1:1+i].isdigit(): return (1+i, int(txt[1:1+i], 8)) else: try: return chr_esc[c] except KeyError: raise PreprocError("could not parse char literal '%s'" % txt) def tokenize(s): """ Convert a string into a list of tokens (shlex.split does not apply to c/c++/d) :param s: input to tokenize :type s: string :return: a list of tokens :rtype: list of tuple(token, value) """ return tokenize_private(s)[:] # force a copy of the results @Utils.run_once def tokenize_private(s): ret = [] for match in re_clexer.finditer(s): m = match.group for name in tok_types: v = m(name) if v: if name == IDENT: try: g_optrans[v]; name = OP except KeyError: # c++ specific if v.lower() == "true": v = 1 name = NUM elif v.lower() == "false": v = 0 name = NUM elif name == NUM: if m('oct'): v = int(v, 8) elif m('hex'): v = int(m('hex'), 16) elif m('n0'): v = m('n0') else: v = m('char') if v: v = parse_char(v) else: v = m('n2') or m('n4') elif name == OP: if v == '%:': v = '#' elif v == '%:%:': v = '##' elif name == STR: # remove the quotes around the string v = v[1:-1] ret.append((name, v)) break return ret @Utils.run_once def define_name(line): """ :param line: define line :type line: string :rtype: string :return: the define name """ return re_mac.match(line).group(0) class c_parser(object): """ Used by :py:func:`waflib.Tools.c_preproc.scan` to parse c/h files. Note that by default, only project headers are parsed. """ def __init__(self, nodepaths=None, defines=None): self.lines = [] """list of lines read""" if defines is None: self.defs = {} else: self.defs = dict(defines) # make a copy self.state = [] self.count_files = 0 self.currentnode_stack = [] self.nodepaths = nodepaths or [] """Include paths""" self.nodes = [] """List of :py:class:`waflib.Node.Node` found so far""" self.names = [] """List of file names that could not be matched by any file""" self.curfile = '' """Current file""" self.ban_includes = set([]) """Includes that must not be read (#pragma once)""" def cached_find_resource(self, node, filename): """ Find a file from the input directory :param node: directory :type node: :py:class:`waflib.Node.Node` :param filename: header to find :type filename: string :return: the node if found, or None :rtype: :py:class:`waflib.Node.Node` """ try: nd = node.ctx.cache_nd except AttributeError: nd = node.ctx.cache_nd = {} tup = (node, filename) try: return nd[tup] except KeyError: ret = node.find_resource(filename) if ret: if getattr(ret, 'children', None): ret = None elif ret.is_child_of(node.ctx.bldnode): tmp = node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode)) if tmp and getattr(tmp, 'children', None): ret = None nd[tup] = ret return ret def tryfind(self, filename): """ Try to obtain a node from the filename based from the include paths. Will add the node found to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` or the file name to :py:attr:`waflib.Tools.c_preproc.c_parser.names` if no corresponding file is found. Called by :py:attr:`waflib.Tools.c_preproc.c_parser.start`. :param filename: header to find :type filename: string :return: the node if found :rtype: :py:class:`waflib.Node.Node` """ if filename.endswith('.moc'): # we could let the qt4 module use a subclass, but then the function "scan" below must be duplicated # in the qt4 and in the qt5 classes. So we have two lines here and it is sufficient. TODO waf 1.9 self.names.append(filename) return None self.curfile = filename # for msvc it should be a for loop over the whole stack found = self.cached_find_resource(self.currentnode_stack[-1], filename) for n in self.nodepaths: if found: break found = self.cached_find_resource(n, filename) if found and not found in self.ban_includes: # TODO duplicates do not increase the no-op build times too much, but they may be worth removing self.nodes.append(found) self.addlines(found) else: if not filename in self.names: self.names.append(filename) return found def addlines(self, node): """ Add the lines from a header in the list of preprocessor lines to parse :param node: header :type node: :py:class:`waflib.Node.Node` """ self.currentnode_stack.append(node.parent) filepath = node.abspath() self.count_files += 1 if self.count_files > recursion_limit: # issue #812 raise PreprocError("recursion limit exceeded") pc = self.parse_cache debug('preproc: reading file %r', filepath) try: lns = pc[filepath] except KeyError: pass else: self.lines.extend(lns) return try: lines = filter_comments(filepath) lines.append((POPFILE, '')) lines.reverse() pc[filepath] = lines # cache the lines filtered self.lines.extend(lines) except IOError: raise PreprocError("could not read the file %s" % filepath) except Exception: if Logs.verbose > 0: error("parsing %s failed" % filepath) traceback.print_exc() def start(self, node, env): """ Preprocess a source file to obtain the dependencies, which are accumulated to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` and :py:attr:`waflib.Tools.c_preproc.c_parser.names`. :param node: source file :type node: :py:class:`waflib.Node.Node` :param env: config set containing additional defines to take into account :type env: :py:class:`waflib.ConfigSet.ConfigSet` """ debug('preproc: scanning %s (in %s)', node.name, node.parent.name) bld = node.ctx try: self.parse_cache = bld.parse_cache except AttributeError: self.parse_cache = bld.parse_cache = {} self.current_file = node self.addlines(node) # macros may be defined on the command-line, so they must be parsed as if they were part of the file if env['DEFINES']: try: lst = ['%s %s' % (x[0], trimquotes('='.join(x[1:]))) for x in [y.split('=') for y in env['DEFINES']]] lst.reverse() self.lines.extend([('define', x) for x in lst]) except AttributeError: # if the defines are invalid the compiler will tell the user pass while self.lines: (token, line) = self.lines.pop() if token == POPFILE: self.count_files -= 1 self.currentnode_stack.pop() continue try: ve = Logs.verbose if ve: debug('preproc: line is %s - %s state is %s', token, line, self.state) state = self.state # make certain we define the state if we are about to enter in an if block if token[:2] == 'if': state.append(undefined) elif token == 'endif': state.pop() # skip lines when in a dead 'if' branch, wait for the endif if token[0] != 'e': if skipped in self.state or ignored in self.state: continue if token == 'if': ret = eval_macro(tokenize(line), self.defs) if ret: state[-1] = accepted else: state[-1] = ignored elif token == 'ifdef': m = re_mac.match(line) if m and m.group(0) in self.defs: state[-1] = accepted else: state[-1] = ignored elif token == 'ifndef': m = re_mac.match(line) if m and m.group(0) in self.defs: state[-1] = ignored else: state[-1] = accepted elif token == 'include' or token == 'import': (kind, inc) = extract_include(line, self.defs) if ve: debug('preproc: include found %s (%s) ', inc, kind) if kind == '"' or not strict_quotes: self.current_file = self.tryfind(inc) if token == 'import': self.ban_includes.add(self.current_file) elif token == 'elif': if state[-1] == accepted: state[-1] = skipped elif state[-1] == ignored: if eval_macro(tokenize(line), self.defs): state[-1] = accepted elif token == 'else': if state[-1] == accepted: state[-1] = skipped elif state[-1] == ignored: state[-1] = accepted elif token == 'define': try: self.defs[define_name(line)] = line except Exception: raise PreprocError("Invalid define line %s" % line) elif token == 'undef': m = re_mac.match(line) if m and m.group(0) in self.defs: self.defs.__delitem__(m.group(0)) #print "undef %s" % name elif token == 'pragma': if re_pragma_once.match(line.lower()): self.ban_includes.add(self.current_file) except Exception as e: if Logs.verbose: debug('preproc: line parsing failed (%s): %s %s', e, line, Utils.ex_stack()) def scan(task): """ Get the dependencies using a c/c++ preprocessor, this is required for finding dependencies of the kind:: #include some_macro() This function is bound as a task method on :py:class:`waflib.Tools.c.c` and :py:class:`waflib.Tools.cxx.cxx` for example """ global go_absolute try: incn = task.generator.includes_nodes except AttributeError: raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": ' % task.generator) if go_absolute: nodepaths = incn + [task.generator.bld.root.find_dir(x) for x in standard_includes] else: nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)] tmp = c_parser(nodepaths) tmp.start(task.inputs[0], task.env) if Logs.verbose: debug('deps: deps for %r: %r; unresolved %r' % (task.inputs, tmp.nodes, tmp.names)) return (tmp.nodes, tmp.names) 1.9.12~dfsg/waflib/Tools/cxx.py0000644000000000000000000000314013214314510015056 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) "Base for c++ programs and libraries" from waflib import TaskGen, Task from waflib.Tools import c_preproc from waflib.Tools.ccroot import link_task, stlink_task @TaskGen.extension('.cpp','.cc','.cxx','.C','.c++') def cxx_hook(self, node): "Bind the c++ file extensions to the creation of a :py:class:`waflib.Tools.cxx.cxx` instance" return self.create_compiled_task('cxx', node) if not '.c' in TaskGen.task_gen.mappings: TaskGen.task_gen.mappings['.c'] = TaskGen.task_gen.mappings['.cpp'] class cxx(Task.Task): "Compile C++ files into object files" run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()}' vars = ['CXXDEPS'] # unused variable to depend on, just in case ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] scan = c_preproc.scan class cxxprogram(link_task): "Link object files into a c++ program" run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' vars = ['LINKDEPS'] ext_out = ['.bin'] inst_to = '${BINDIR}' class cxxshlib(cxxprogram): "Link object files into a c++ shared library" inst_to = '${LIBDIR}' class cxxstlib(stlink_task): "Link object files into a c++ static library" pass # do not remove 1.9.12~dfsg/waflib/Tools/clangxx.py0000644000000000000000000000120613214314510015721 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy 2009-2010 (ita) """ Detect the Clang++ C++ compiler """ from waflib.Tools import ccroot, ar, gxx from waflib.Configure import conf @conf def find_clangxx(conf): """ Find the program clang++, and execute it to ensure it really is clang++ """ cxx = conf.find_program('clang++', var='CXX') conf.get_cc_version(cxx, clang=True) conf.env.CXX_NAME = 'clang' def configure(conf): conf.find_clangxx() conf.find_program(['llvm-ar', 'ar'], var='AR') conf.find_ar() conf.gxx_common_flags() conf.gxx_modifier_platform() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/c_osx.py0000644000000000000000000001452313214314510015376 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy 2008-2010 """ MacOSX related tools """ import os, shutil, platform from waflib import Task, Utils, Errors from waflib.TaskGen import taskgen_method, feature, after_method, before_method app_info = ''' CFBundlePackageType APPL CFBundleGetInfoString Created by Waf CFBundleSignature ???? NOTE THIS IS A GENERATED FILE, DO NOT MODIFY CFBundleExecutable {app_name} ''' """ plist template """ @feature('c', 'cxx') def set_macosx_deployment_target(self): """ see WAF issue 285 and also and also http://trac.macports.org/ticket/17059 """ if self.env['MACOSX_DEPLOYMENT_TARGET']: os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env['MACOSX_DEPLOYMENT_TARGET'] elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ: if Utils.unversioned_sys_platform() == 'darwin': os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2]) @taskgen_method def create_bundle_dirs(self, name, out): """ Create bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp` """ dir = out.parent.find_or_declare(name) dir.mkdir() macos = dir.find_or_declare(['Contents', 'MacOS']) macos.mkdir() return dir def bundle_name_for_output(out): name = out.name k = name.rfind('.') if k >= 0: name = name[:k] + '.app' else: name = name + '.app' return name @feature('cprogram', 'cxxprogram') @after_method('apply_link') def create_task_macapp(self): """ To compile an executable into a Mac application (a .app), set its *mac_app* attribute:: def build(bld): bld.shlib(source='a.c', target='foo', mac_app=True) To force *all* executables to be transformed into Mac applications:: def build(bld): bld.env.MACAPP = True bld.shlib(source='a.c', target='foo') """ if self.env['MACAPP'] or getattr(self, 'mac_app', False): out = self.link_task.outputs[0] name = bundle_name_for_output(out) dir = self.create_bundle_dirs(name, out) n1 = dir.find_or_declare(['Contents', 'MacOS', out.name]) self.apptask = self.create_task('macapp', self.link_task.outputs, n1) inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/MacOS/' % name self.bld.install_files(inst_to, n1, chmod=Utils.O755) if getattr(self, 'mac_files', None): # this only accepts files; they will be installed as seen from mac_files_root mac_files_root = getattr(self, 'mac_files_root', None) if isinstance(mac_files_root, str): mac_files_root = self.path.find_node(mac_files_root) if not mac_files_root: self.bld.fatal('Invalid mac_files_root %r' % self.mac_files_root) res_dir = n1.parent.parent.make_node('Resources') inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name for node in self.to_nodes(self.mac_files): relpath = node.path_from(mac_files_root or node.parent) self.create_task('macapp', node, res_dir.make_node(relpath)) self.bld.install_as(os.path.join(inst_to, relpath), node) if getattr(self, 'mac_resources', None): # TODO remove in waf 1.9 res_dir = n1.parent.parent.make_node('Resources') inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name for x in self.to_list(self.mac_resources): node = self.path.find_node(x) if not node: raise Errors.WafError('Missing mac_resource %r in %r' % (x, self)) parent = node.parent if os.path.isdir(node.abspath()): nodes = node.ant_glob('**') else: nodes = [node] for node in nodes: rel = node.path_from(parent) self.create_task('macapp', node, res_dir.make_node(rel)) self.bld.install_as(inst_to + '/%s' % rel, node) if getattr(self.bld, 'is_install', None): # disable the normal binary installation self.install_task.hasrun = Task.SKIP_ME @feature('cprogram', 'cxxprogram') @after_method('apply_link') def create_task_macplist(self): """ Create a :py:class:`waflib.Tools.c_osx.macplist` instance. """ if self.env['MACAPP'] or getattr(self, 'mac_app', False): out = self.link_task.outputs[0] name = bundle_name_for_output(out) dir = self.create_bundle_dirs(name, out) n1 = dir.find_or_declare(['Contents', 'Info.plist']) self.plisttask = plisttask = self.create_task('macplist', [], n1) plisttask.context = { 'app_name': self.link_task.outputs[0].name, 'env': self.env } plist_ctx = getattr(self, 'plist_context', None) if (plist_ctx): plisttask.context.update(plist_ctx) if getattr(self, 'mac_plist', False): node = self.path.find_resource(self.mac_plist) if node: plisttask.inputs.append(node) else: plisttask.code = self.mac_plist else: plisttask.code = app_info inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/' % name self.bld.install_files(inst_to, n1) @feature('cshlib', 'cxxshlib') @before_method('apply_link', 'propagate_uselib_vars') def apply_bundle(self): """ To make a bundled shared library (a ``.bundle``), set the *mac_bundle* attribute:: def build(bld): bld.shlib(source='a.c', target='foo', mac_bundle = True) To force *all* executables to be transformed into bundles:: def build(bld): bld.env.MACBUNDLE = True bld.shlib(source='a.c', target='foo') """ if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False): self.env['LINKFLAGS_cshlib'] = self.env['LINKFLAGS_cxxshlib'] = [] # disable the '-dynamiclib' flag self.env['cshlib_PATTERN'] = self.env['cxxshlib_PATTERN'] = self.env['macbundle_PATTERN'] use = self.use = self.to_list(getattr(self, 'use', [])) if not 'MACBUNDLE' in use: use.append('MACBUNDLE') app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources'] class macapp(Task.Task): """ Create mac applications """ color = 'PINK' def run(self): self.outputs[0].parent.mkdir() shutil.copy2(self.inputs[0].srcpath(), self.outputs[0].abspath()) class macplist(Task.Task): """ Create plist files """ color = 'PINK' ext_in = ['.bin'] def run(self): if getattr(self, 'code', None): txt = self.code else: txt = self.inputs[0].read() context = getattr(self, 'context', {}) txt = txt.format(**context) self.outputs[0].write(txt) 1.9.12~dfsg/waflib/Tools/c_tests.py0000644000000000000000000001343013214314510015723 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010 (ita) """ Various configuration tests. """ from waflib import Task from waflib.Configure import conf from waflib.TaskGen import feature, before_method, after_method LIB_CODE = ''' #ifdef _MSC_VER #define testEXPORT __declspec(dllexport) #else #define testEXPORT #endif testEXPORT int lib_func(void) { return 9; } ''' MAIN_CODE = ''' #ifdef _MSC_VER #define testEXPORT __declspec(dllimport) #else #define testEXPORT #endif testEXPORT int lib_func(void); int main(int argc, char **argv) { (void)argc; (void)argv; return !(lib_func() == 9); } ''' @feature('link_lib_test') @before_method('process_source') def link_lib_test_fun(self): """ The configuration test :py:func:`waflib.Configure.run_build` declares a unique task generator, so we need to create other task generators from here to check if the linker is able to link libraries. """ def write_test_file(task): task.outputs[0].write(task.generator.code) rpath = [] if getattr(self, 'add_rpath', False): rpath = [self.bld.path.get_bld().abspath()] mode = self.mode m = '%s %s' % (mode, mode) ex = self.test_exec and 'test_exec' or '' bld = self.bld bld(rule=write_test_file, target='test.' + mode, code=LIB_CODE) bld(rule=write_test_file, target='main.' + mode, code=MAIN_CODE) bld(features='%sshlib' % m, source='test.' + mode, target='test') bld(features='%sprogram %s' % (m, ex), source='main.' + mode, target='app', use='test', rpath=rpath) @conf def check_library(self, mode=None, test_exec=True): """ Check if libraries can be linked with the current linker. Uses :py:func:`waflib.Tools.c_tests.link_lib_test_fun`. :param mode: c or cxx or d :type mode: string """ if not mode: mode = 'c' if self.env.CXX: mode = 'cxx' self.check( compile_filename = [], features = 'link_lib_test', msg = 'Checking for libraries', mode = mode, test_exec = test_exec, ) ######################################################################################## INLINE_CODE = ''' typedef int foo_t; static %s foo_t static_foo () {return 0; } %s foo_t foo () { return 0; } ''' INLINE_VALUES = ['inline', '__inline__', '__inline'] @conf def check_inline(self, **kw): """ Check for the right value for inline macro. Define INLINE_MACRO to 1 if the define is found. If the inline macro is not 'inline', add a define to the ``config.h`` (#define inline __inline__) :param define_name: define INLINE_MACRO by default to 1 if the macro is defined :type define_name: string :param features: by default *c* or *cxx* depending on the compiler present :type features: list of string """ self.start_msg('Checking for inline') if not 'define_name' in kw: kw['define_name'] = 'INLINE_MACRO' if not 'features' in kw: if self.env.CXX: kw['features'] = ['cxx'] else: kw['features'] = ['c'] for x in INLINE_VALUES: kw['fragment'] = INLINE_CODE % (x, x) try: self.check(**kw) except self.errors.ConfigurationError: continue else: self.end_msg(x) if x != 'inline': self.define('inline', x, quote=False) return x self.fatal('could not use inline functions') ######################################################################################## LARGE_FRAGMENT = '''#include int main(int argc, char **argv) { (void)argc; (void)argv; return !(sizeof(off_t) >= 8); } ''' @conf def check_large_file(self, **kw): """ Check for large file support and define the macro HAVE_LARGEFILE The test is skipped on win32 systems (DEST_BINFMT == pe). :param define_name: define to set, by default *HAVE_LARGEFILE* :type define_name: string :param execute: execute the test (yes by default) :type execute: bool """ if not 'define_name' in kw: kw['define_name'] = 'HAVE_LARGEFILE' if not 'execute' in kw: kw['execute'] = True if not 'features' in kw: if self.env.CXX: kw['features'] = ['cxx', 'cxxprogram'] else: kw['features'] = ['c', 'cprogram'] kw['fragment'] = LARGE_FRAGMENT kw['msg'] = 'Checking for large file support' ret = True try: if self.env.DEST_BINFMT != 'pe': ret = self.check(**kw) except self.errors.ConfigurationError: pass else: if ret: return True kw['msg'] = 'Checking for -D_FILE_OFFSET_BITS=64' kw['defines'] = ['_FILE_OFFSET_BITS=64'] try: ret = self.check(**kw) except self.errors.ConfigurationError: pass else: self.define('_FILE_OFFSET_BITS', 64) return ret self.fatal('There is no support for large files') ######################################################################################## ENDIAN_FRAGMENT = ''' short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; ''' class grep_for_endianness(Task.Task): color = 'PINK' def run(self): txt = self.inputs[0].read(flags='rb').decode('iso8859-1') if txt.find('LiTTleEnDian') > -1: self.generator.tmp.append('little') elif txt.find('BIGenDianSyS') > -1: self.generator.tmp.append('big') else: return -1 @feature('grep_for_endianness') @after_method('process_source') def grep_for_endianness_fun(self): """ Used by the endiannes configuration test """ self.create_task('grep_for_endianness', self.compiled_tasks[0].outputs[0]) @conf def check_endianness(self): """ Execute a configuration test to determine the endianness """ tmp = [] def check_msg(self): return tmp[0] self.check(fragment=ENDIAN_FRAGMENT, features='c grep_for_endianness', msg="Checking for endianness", define='ENDIANNESS', tmp=tmp, okmsg=check_msg) return tmp[0] 1.9.12~dfsg/waflib/Tools/compiler_c.py0000644000000000000000000000600113214314510016367 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Matthias Jahn jahn dôt matthias ât freenet dôt de, 2007 (pmarat) """ Try to detect a C compiler from the list of supported compilers (gcc, msvc, etc):: def options(opt): opt.load('compiler_c') def configure(cnf): cnf.load('compiler_c') def build(bld): bld.program(source='main.c', target='app') The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_c.c_compiler`. To register a new C compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use:: from waflib.Tools.compiler_c import c_compiler c_compiler['win32'] = ['cfoo', 'msvc', 'gcc'] def options(opt): opt.load('compiler_c') def configure(cnf): cnf.load('compiler_c') def build(bld): bld.program(source='main.c', target='app') Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using:: $ CC=clang waf configure """ import re from waflib.Tools import ccroot from waflib import Utils from waflib.Logs import debug c_compiler = { 'win32': ['msvc', 'gcc', 'clang'], 'cygwin': ['gcc'], 'darwin': ['clang', 'gcc'], 'aix': ['xlc', 'gcc', 'clang'], 'linux': ['gcc', 'clang', 'icc'], 'sunos': ['suncc', 'gcc'], 'irix': ['gcc', 'irixcc'], 'hpux': ['gcc'], 'osf1V': ['gcc'], 'gnu': ['gcc', 'clang'], 'java': ['gcc', 'msvc', 'clang', 'icc'], 'default':['gcc', 'clang'], } """ Dict mapping the platform names to Waf tools finding specific C compilers:: from waflib.Tools.compiler_c import c_compiler c_compiler['linux'] = ['gcc', 'icc', 'suncc'] """ def default_compilers(): build_platform = Utils.unversioned_sys_platform() possible_compiler_list = c_compiler.get(build_platform, c_compiler['default']) return ' '.join(possible_compiler_list) def configure(conf): """ Try to find a suitable C compiler or raise a :py:class:`waflib.Errors.ConfigurationError`. """ try: test_for_compiler = conf.options.check_c_compiler or default_compilers() except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_c')") for compiler in re.split('[ ,]+', test_for_compiler): conf.env.stash() conf.start_msg('Checking for %r (C compiler)' % compiler) try: conf.load(compiler) except conf.errors.ConfigurationError as e: conf.env.revert() conf.end_msg(False) debug('compiler_c: %r' % e) else: if conf.env['CC']: conf.end_msg(conf.env.get_flat('CC')) conf.env['COMPILER_CC'] = compiler break conf.end_msg(False) else: conf.fatal('could not configure a C compiler!') def options(opt): """ Restrict the compiler detection from the command-line:: $ waf configure --check-c-compiler=gcc """ test_for_compiler = default_compilers() opt.load_special_tools('c_*.py', ban=['c_dumbpreproc.py']) cc_compiler_opts = opt.add_option_group('Configuration options') cc_compiler_opts.add_option('--check-c-compiler', default=None, help='list of C compilers to try [%s]' % test_for_compiler, dest="check_c_compiler") for x in test_for_compiler.split(): opt.load('%s' % x) 1.9.12~dfsg/waflib/Tools/suncc.py0000644000000000000000000000303713214314510015374 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_scc(conf): """ Detect the Sun C compiler """ v = conf.env cc = conf.find_program('cc', var='CC') try: conf.cmd_and_log(cc + ['-flags']) except Exception: conf.fatal('%r is not a Sun compiler' % cc) v.CC_NAME = 'sun' conf.get_suncc_version(cc) @conf def scc_common_flags(conf): """ Flags required for executing the sun C compiler """ v = conf.env v['CC_SRC_F'] = [] v['CC_TGT_F'] = ['-c', '-o'] # linker if not v['LINK_CC']: v['LINK_CC'] = v['CC'] v['CCLNK_SRC_F'] = '' v['CCLNK_TGT_F'] = ['-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-D%s' v['LIB_ST'] = '-l%s' # template for adding libs v['LIBPATH_ST'] = '-L%s' # template for adding libpaths v['STLIB_ST'] = '-l%s' v['STLIBPATH_ST'] = '-L%s' v['SONAME_ST'] = '-Wl,-h,%s' v['SHLIB_MARKER'] = '-Bdynamic' v['STLIB_MARKER'] = '-Bstatic' # program v['cprogram_PATTERN'] = '%s' # shared library v['CFLAGS_cshlib'] = ['-xcode=pic32', '-DPIC'] v['LINKFLAGS_cshlib'] = ['-G'] v['cshlib_PATTERN'] = 'lib%s.so' # static lib v['LINKFLAGS_cstlib'] = ['-Bstatic'] v['cstlib_PATTERN'] = 'lib%s.a' def configure(conf): conf.find_scc() conf.find_ar() conf.scc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/gxx.py0000644000000000000000000001024113214314510015062 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) # Yinon Ehrlich, 2009 """ g++/llvm detection. """ from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_gxx(conf): """ Find the program g++, and if present, try to detect its version number """ cxx = conf.find_program(['g++', 'c++'], var='CXX') conf.get_cc_version(cxx, gcc=True) conf.env.CXX_NAME = 'gcc' @conf def gxx_common_flags(conf): """ Common flags for g++ on nearly all platforms """ v = conf.env v['CXX_SRC_F'] = [] v['CXX_TGT_F'] = ['-c', '-o'] # linker if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX'] v['CXXLNK_SRC_F'] = [] v['CXXLNK_TGT_F'] = ['-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-D%s' v['LIB_ST'] = '-l%s' # template for adding libs v['LIBPATH_ST'] = '-L%s' # template for adding libpaths v['STLIB_ST'] = '-l%s' v['STLIBPATH_ST'] = '-L%s' v['RPATH_ST'] = '-Wl,-rpath,%s' v['SONAME_ST'] = '-Wl,-h,%s' v['SHLIB_MARKER'] = '-Wl,-Bdynamic' v['STLIB_MARKER'] = '-Wl,-Bstatic' # program v['cxxprogram_PATTERN'] = '%s' # shared library v['CXXFLAGS_cxxshlib'] = ['-fPIC'] v['LINKFLAGS_cxxshlib'] = ['-shared'] v['cxxshlib_PATTERN'] = 'lib%s.so' # static lib v['LINKFLAGS_cxxstlib'] = ['-Wl,-Bstatic'] v['cxxstlib_PATTERN'] = 'lib%s.a' # osx stuff v['LINKFLAGS_MACBUNDLE'] = ['-bundle', '-undefined', 'dynamic_lookup'] v['CXXFLAGS_MACBUNDLE'] = ['-fPIC'] v['macbundle_PATTERN'] = '%s.bundle' @conf def gxx_modifier_win32(conf): """Configuration flags for executing gcc on Windows""" v = conf.env v['cxxprogram_PATTERN'] = '%s.exe' v['cxxshlib_PATTERN'] = '%s.dll' v['implib_PATTERN'] = 'lib%s.dll.a' v['IMPLIB_ST'] = '-Wl,--out-implib,%s' v['CXXFLAGS_cxxshlib'] = [] # Auto-import is enabled by default even without this option, # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages # that the linker emits otherwise. v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) @conf def gxx_modifier_cygwin(conf): """Configuration flags for executing g++ on Cygwin""" gxx_modifier_win32(conf) v = conf.env v['cxxshlib_PATTERN'] = 'cyg%s.dll' v.append_value('LINKFLAGS_cxxshlib', ['-Wl,--enable-auto-image-base']) v['CXXFLAGS_cxxshlib'] = [] @conf def gxx_modifier_darwin(conf): """Configuration flags for executing g++ on MacOS""" v = conf.env v['CXXFLAGS_cxxshlib'] = ['-fPIC'] v['LINKFLAGS_cxxshlib'] = ['-dynamiclib'] v['cxxshlib_PATTERN'] = 'lib%s.dylib' v['FRAMEWORKPATH_ST'] = '-F%s' v['FRAMEWORK_ST'] = ['-framework'] v['ARCH_ST'] = ['-arch'] v['LINKFLAGS_cxxstlib'] = [] v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] v['SONAME_ST'] = [] @conf def gxx_modifier_aix(conf): """Configuration flags for executing g++ on AIX""" v = conf.env v['LINKFLAGS_cxxprogram']= ['-Wl,-brtl'] v['LINKFLAGS_cxxshlib'] = ['-shared', '-Wl,-brtl,-bexpfull'] v['SHLIB_MARKER'] = [] @conf def gxx_modifier_hpux(conf): v = conf.env v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] v['CFLAGS_cxxshlib'] = ['-fPIC','-DPIC'] v['cxxshlib_PATTERN'] = 'lib%s.sl' @conf def gxx_modifier_openbsd(conf): conf.env.SONAME_ST = [] @conf def gcc_modifier_osf1V(conf): v = conf.env v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] v['SONAME_ST'] = [] @conf def gxx_modifier_platform(conf): """Execute platform-specific functions based on *gxx_modifier_+NAME*""" # * set configurations specific for a platform. # * the destination platform is detected automatically by looking at the macros the compiler predefines, # and if it's not recognised, it fallbacks to sys.platform. gxx_modifier_func = getattr(conf, 'gxx_modifier_' + conf.env.DEST_OS, None) if gxx_modifier_func: gxx_modifier_func() def configure(conf): """ Configuration for g++ """ conf.find_gxx() conf.find_ar() conf.gxx_common_flags() conf.gxx_modifier_platform() conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Tools/c_config.py0000644000000000000000000011031013214314510016021 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ C/C++/D configuration helpers """ import os, re, shlex from waflib import Build, Utils, Task, Options, Logs, Errors, Runner from waflib.TaskGen import after_method, feature from waflib.Configure import conf WAF_CONFIG_H = 'config.h' """default name for the config.h file""" DEFKEYS = 'define_key' INCKEYS = 'include_key' cfg_ver = { 'atleast-version': '>=', 'exact-version': '==', 'max-version': '<=', } SNIP_FUNCTION = ''' int main(int argc, char **argv) { void (*p)(); (void)argc; (void)argv; p=(void(*)())(%s); return !p; } ''' """Code template for checking for functions""" SNIP_TYPE = ''' int main(int argc, char **argv) { (void)argc; (void)argv; if ((%(type_name)s *) 0) return 0; if (sizeof (%(type_name)s)) return 0; return 1; } ''' """Code template for checking for types""" SNIP_EMPTY_PROGRAM = ''' int main(int argc, char **argv) { (void)argc; (void)argv; return 0; } ''' SNIP_FIELD = ''' int main(int argc, char **argv) { char *off; (void)argc; (void)argv; off = (char*) &((%(type_name)s*)0)->%(field_name)s; return (size_t) off < sizeof(%(type_name)s); } ''' MACRO_TO_DESTOS = { '__linux__' : 'linux', '__GNU__' : 'gnu', # hurd '__FreeBSD__' : 'freebsd', '__NetBSD__' : 'netbsd', '__OpenBSD__' : 'openbsd', '__sun' : 'sunos', '__hpux' : 'hpux', '__sgi' : 'irix', '_AIX' : 'aix', '__CYGWIN__' : 'cygwin', '__MSYS__' : 'cygwin', '_UWIN' : 'uwin', '_WIN64' : 'win32', '_WIN32' : 'win32', # Note about darwin: this is also tested with 'defined __APPLE__ && defined __MACH__' somewhere below in this file. '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' : 'darwin', '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' : 'darwin', # iphone '__QNX__' : 'qnx', '__native_client__' : 'nacl' # google native client platform } MACRO_TO_DEST_CPU = { '__x86_64__' : 'x86_64', '__amd64__' : 'x86_64', '__i386__' : 'x86', '__ia64__' : 'ia', '__mips__' : 'mips', '__sparc__' : 'sparc', '__alpha__' : 'alpha', '__aarch64__' : 'aarch64', '__thumb__' : 'thumb', '__arm__' : 'arm', '__hppa__' : 'hppa', '__powerpc__' : 'powerpc', '__ppc__' : 'powerpc', '__convex__' : 'convex', '__m68k__' : 'm68k', '__s390x__' : 's390x', '__s390__' : 's390', '__sh__' : 'sh', } @conf def parse_flags(self, line, uselib_store, env=None, force_static=False, posix=None): """ Parse the flags from the input lines, and add them to the relevant use variables:: def configure(conf): conf.parse_flags('-O3', 'FOO') # conf.env.CXXFLAGS_FOO = ['-O3'] # conf.env.CFLAGS_FOO = ['-O3'] :param line: flags :type line: string :param uselib_store: where to add the flags :type uselib_store: string :param env: config set or conf.env by default :type env: :py:class:`waflib.ConfigSet.ConfigSet` """ assert(isinstance(line, str)) env = env or self.env # Issue 811 and 1371 if posix is None: posix = True if '\\' in line: posix = ('\\ ' in line) or ('\\\\' in line) lex = shlex.shlex(line, posix=posix) lex.whitespace_split = True lex.commenters = '' lst = list(lex) # append_unique is not always possible # for example, apple flags may require both -arch i386 and -arch ppc app = env.append_value appu = env.append_unique uselib = uselib_store static = False while lst: x = lst.pop(0) st = x[:2] ot = x[2:] if st == '-I' or st == '/I': if not ot: ot = lst.pop(0) appu('INCLUDES_' + uselib, [ot]) elif st == '-i': tmp = [x, lst.pop(0)] app('CFLAGS', tmp) app('CXXFLAGS', tmp) elif st == '-D' or (env.CXX_NAME == 'msvc' and st == '/D'): # not perfect but.. if not ot: ot = lst.pop(0) app('DEFINES_' + uselib, [ot]) elif st == '-l': if not ot: ot = lst.pop(0) prefix = (force_static or static) and 'STLIB_' or 'LIB_' appu(prefix + uselib, [ot]) elif st == '-L': if not ot: ot = lst.pop(0) prefix = (force_static or static) and 'STLIBPATH_' or 'LIBPATH_' appu(prefix + uselib, [ot]) elif x.startswith('/LIBPATH:'): prefix = (force_static or static) and 'STLIBPATH_' or 'LIBPATH_' appu(prefix + uselib, [x.replace('/LIBPATH:', '')]) elif x == '-pthread' or x.startswith('+') or x.startswith('-std'): app('CFLAGS_' + uselib, [x]) app('CXXFLAGS_' + uselib, [x]) app('LINKFLAGS_' + uselib, [x]) elif x == '-framework': appu('FRAMEWORK_' + uselib, [lst.pop(0)]) elif x.startswith('-F'): appu('FRAMEWORKPATH_' + uselib, [x[2:]]) elif x == '-Wl,-rpath' or x == '-Wl,-R': app('RPATH_' + uselib, lst.pop(0).lstrip('-Wl,')) elif x.startswith('-Wl,-R,'): app('RPATH_' + uselib, x[7:]) elif x.startswith('-Wl,-R'): app('RPATH_' + uselib, x[6:]) elif x.startswith('-Wl,-rpath,'): app('RPATH_' + uselib, x[11:]) elif x == '-Wl,-Bstatic' or x == '-Bstatic': static = True elif x == '-Wl,-Bdynamic' or x == '-Bdynamic': static = False elif x.startswith('-Wl'): app('LINKFLAGS_' + uselib, [x]) elif x.startswith('-m') or x.startswith('-f') or x.startswith('-dynamic'): app('CFLAGS_' + uselib, [x]) app('CXXFLAGS_' + uselib, [x]) elif x.startswith('-bundle'): app('LINKFLAGS_' + uselib, [x]) elif x.startswith('-undefined') or x.startswith('-Xlinker'): arg = lst.pop(0) app('LINKFLAGS_' + uselib, [x, arg]) elif x.startswith('-arch') or x.startswith('-isysroot'): tmp = [x, lst.pop(0)] app('CFLAGS_' + uselib, tmp) app('CXXFLAGS_' + uselib, tmp) app('LINKFLAGS_' + uselib, tmp) elif x.endswith('.a') or x.endswith('.so') or x.endswith('.dylib') or x.endswith('.lib'): appu('LINKFLAGS_' + uselib, [x]) # not cool, #762 @conf def validate_cfg(self, kw): """ Search for the program *pkg-config* if missing, and validate the parameters to pass to :py:func:`waflib.Tools.c_config.exec_cfg`. :param path: the **-config program to use** (default is *pkg-config*) :type path: list of string :param msg: message to display to describe the test executed :type msg: string :param okmsg: message to display when the test is successful :type okmsg: string :param errmsg: message to display in case of error :type errmsg: string """ if not 'path' in kw: if not self.env.PKGCONFIG: self.find_program('pkg-config', var='PKGCONFIG') kw['path'] = self.env.PKGCONFIG # pkg-config version if 'atleast_pkgconfig_version' in kw: if not 'msg' in kw: kw['msg'] = 'Checking for pkg-config version >= %r' % kw['atleast_pkgconfig_version'] return if not 'okmsg' in kw: kw['okmsg'] = 'yes' if not 'errmsg' in kw: kw['errmsg'] = 'not found' if 'modversion' in kw: if not 'msg' in kw: kw['msg'] = 'Checking for %r version' % kw['modversion'] return # checking for the version of a module, for the moment, one thing at a time for x in cfg_ver.keys(): y = x.replace('-', '_') if y in kw: if not 'package' in kw: raise ValueError('%s requires a package' % x) if not 'msg' in kw: kw['msg'] = 'Checking for %r %s %s' % (kw['package'], cfg_ver[x], kw[y]) return if not 'define_name' in kw: pkgname = kw.get('uselib_store', kw['package'].upper()) kw['define_name'] = self.have_define(pkgname) if not 'uselib_store' in kw: self.undefine(kw['define_name']) if not 'msg' in kw: kw['msg'] = 'Checking for %r' % (kw['package'] or kw['path']) @conf def exec_cfg(self, kw): """ Execute the program *pkg-config*: * if atleast_pkgconfig_version is given, check that pkg-config has the version n and return * if modversion is given, then return the module version * else, execute the *-config* program with the *args* and *variables* given, and set the flags on the *conf.env.FLAGS_name* variable :param atleast_pkgconfig_version: minimum pkg-config version to use (disable other tests) :type atleast_pkgconfig_version: string :param package: package name, for example *gtk+-2.0* :type package: string :param uselib_store: if the test is successful, define HAVE\_*name*. It is also used to define *conf.env.FLAGS_name* variables. :type uselib_store: string :param modversion: if provided, return the version of the given module and define *name*\_VERSION :type modversion: string :param args: arguments to give to *package* when retrieving flags :type args: list of string :param variables: return the values of particular variables :type variables: list of string :param define_variable: additional variables to define (also in conf.env.PKG_CONFIG_DEFINES) :type define_variable: dict(string: string) """ path = Utils.to_list(kw['path']) env = self.env.env or None def define_it(): pkgname = kw.get('uselib_store', kw['package'].upper()) if kw.get('global_define'): # compatibility, replace by pkgname in WAF 1.9? self.define(self.have_define(kw['package']), 1, False) else: self.env.append_unique('DEFINES_%s' % pkgname, "%s=1" % self.have_define(pkgname)) self.env[self.have_define(pkgname)] = 1 # pkg-config version if 'atleast_pkgconfig_version' in kw: cmd = path + ['--atleast-pkgconfig-version=%s' % kw['atleast_pkgconfig_version']] self.cmd_and_log(cmd, env=env) if not 'okmsg' in kw: kw['okmsg'] = 'yes' return # checking for the version of a module for x in cfg_ver: y = x.replace('-', '_') if y in kw: self.cmd_and_log(path + ['--%s=%s' % (x, kw[y]), kw['package']], env=env) if not 'okmsg' in kw: kw['okmsg'] = 'yes' define_it() break # retrieving the version of a module if 'modversion' in kw: version = self.cmd_and_log(path + ['--modversion', kw['modversion']], env=env).strip() self.define('%s_VERSION' % Utils.quote_define_name(kw.get('uselib_store', kw['modversion'])), version) return version lst = [] + path defi = kw.get('define_variable', None) if not defi: defi = self.env.PKG_CONFIG_DEFINES or {} for key, val in defi.items(): lst.append('--define-variable=%s=%s' % (key, val)) static = kw.get('force_static', False) if 'args' in kw: args = Utils.to_list(kw['args']) if '--static' in args or '--static-libs' in args: static = True lst += args # tools like pkgconf expect the package argument after the -- ones -_- lst.extend(Utils.to_list(kw['package'])) # retrieving variables of a module if 'variables' in kw: v = kw.get('env', self.env) uselib = kw.get('uselib_store', kw['package'].upper()) vars = Utils.to_list(kw['variables']) for v in vars: val = self.cmd_and_log(lst + ['--variable=' + v], env=env).strip() var = '%s_%s' % (uselib, v) v[var] = val if not 'okmsg' in kw: kw['okmsg'] = 'yes' return # so we assume the command-line will output flags to be parsed afterwards ret = self.cmd_and_log(lst, env=env) if not 'okmsg' in kw: kw['okmsg'] = 'yes' define_it() self.parse_flags(ret, kw.get('uselib_store', kw['package'].upper()), kw.get('env', self.env), force_static=static, posix=kw.get('posix', None)) return ret @conf def check_cfg(self, *k, **kw): """ Check for configuration flags using a **-config**-like program (pkg-config, sdl-config, etc). Encapsulate the calls to :py:func:`waflib.Tools.c_config.validate_cfg` and :py:func:`waflib.Tools.c_config.exec_cfg` A few examples:: def configure(conf): conf.load('compiler_c') conf.check_cfg(package='glib-2.0', args='--libs --cflags') conf.check_cfg(package='glib-2.0', uselib_store='GLIB', atleast_version='2.10.0', args='--cflags --libs') conf.check_cfg(package='pango') conf.check_cfg(package='pango', uselib_store='MYPANGO', args=['--cflags', '--libs']) conf.check_cfg(package='pango', args=['pango >= 0.1.0', 'pango < 9.9.9', '--cflags', '--libs'], msg="Checking for 'pango 0.1.0'") conf.check_cfg(path='sdl-config', args='--cflags --libs', package='', uselib_store='SDL') conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', package='', uselib_store='OPEN_MPI', mandatory=False) # variables conf.check_cfg(package='gtk+-2.0', variables=['includedir', 'prefix'], uselib_store='FOO') print(conf.env.FOO_includedir) """ if k: lst = k[0].split() kw['package'] = lst[0] kw['args'] = ' '.join(lst[1:]) self.validate_cfg(kw) if 'msg' in kw: self.start_msg(kw['msg'], **kw) ret = None try: ret = self.exec_cfg(kw) except self.errors.WafError: if 'errmsg' in kw: self.end_msg(kw['errmsg'], 'YELLOW', **kw) if Logs.verbose > 1: raise else: self.fatal('The configuration failed') else: if not ret: ret = True kw['success'] = ret if 'okmsg' in kw: self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) return ret def build_fun(bld): if bld.kw['compile_filename']: node = bld.srcnode.make_node(bld.kw['compile_filename']) node.write(bld.kw['code']) o = bld(features=bld.kw['features'], source=bld.kw['compile_filename'], target='testprog') for k, v in bld.kw.items(): setattr(o, k, v) if not bld.kw.get('quiet', None): bld.conf.to_log("==>\n%s\n<==" % bld.kw['code']) @conf def validate_c(self, kw): """ pre-check the parameters that will be given to :py:func:`waflib.Configure.run_build` :param compiler: c or cxx (tries to guess what is best) :type compiler: string :param type: cprogram, cshlib, cstlib - not required if *features are given directly* :type type: binary to create :param feature: desired features for the task generator that will execute the test, for example ``cxx cxxstlib`` :type feature: list of string :param fragment: provide a piece of code for the test (default is to let the system create one) :type fragment: string :param uselib_store: define variables after the test is executed (IMPORTANT!) :type uselib_store: string :param use: parameters to use for building (just like the normal *use* keyword) :type use: list of string :param define_name: define to set when the check is over :type define_name: string :param execute: execute the resulting binary :type execute: bool :param define_ret: if execute is set to True, use the execution output in both the define and the return value :type define_ret: bool :param header_name: check for a particular header :type header_name: string :param auto_add_header_name: if header_name was set, add the headers in env.INCKEYS so the next tests will include these headers :type auto_add_header_name: bool """ if not 'build_fun' in kw: kw['build_fun'] = build_fun if not 'env' in kw: kw['env'] = self.env.derive() env = kw['env'] if not 'compiler' in kw and not 'features' in kw: kw['compiler'] = 'c' if env['CXX_NAME'] and Task.classes.get('cxx', None): kw['compiler'] = 'cxx' if not self.env['CXX']: self.fatal('a c++ compiler is required') else: if not self.env['CC']: self.fatal('a c compiler is required') if not 'compile_mode' in kw: kw['compile_mode'] = 'c' if 'cxx' in Utils.to_list(kw.get('features',[])) or kw.get('compiler', '') == 'cxx': kw['compile_mode'] = 'cxx' if not 'type' in kw: kw['type'] = 'cprogram' if not 'features' in kw: if not 'header_name' in kw or kw.get('link_header_test', True): kw['features'] = [kw['compile_mode'], kw['type']] # "c ccprogram" else: kw['features'] = [kw['compile_mode']] else: kw['features'] = Utils.to_list(kw['features']) if not 'compile_filename' in kw: kw['compile_filename'] = 'test.c' + ((kw['compile_mode'] == 'cxx') and 'pp' or '') def to_header(dct): if 'header_name' in dct: dct = Utils.to_list(dct['header_name']) return ''.join(['#include <%s>\n' % x for x in dct]) return '' #OSX if 'framework_name' in kw: fwkname = kw['framework_name'] if not 'uselib_store' in kw: kw['uselib_store'] = fwkname.upper() if not kw.get('no_header', False): if not 'header_name' in kw: kw['header_name'] = [] fwk = '%s/%s.h' % (fwkname, fwkname) if kw.get('remove_dot_h', None): fwk = fwk[:-2] kw['header_name'] = Utils.to_list(kw['header_name']) + [fwk] kw['msg'] = 'Checking for framework %s' % fwkname kw['framework'] = fwkname #kw['frameworkpath'] = set it yourself if 'function_name' in kw: fu = kw['function_name'] if not 'msg' in kw: kw['msg'] = 'Checking for function %s' % fu kw['code'] = to_header(kw) + SNIP_FUNCTION % fu if not 'uselib_store' in kw: kw['uselib_store'] = fu.upper() if not 'define_name' in kw: kw['define_name'] = self.have_define(fu) elif 'type_name' in kw: tu = kw['type_name'] if not 'header_name' in kw: kw['header_name'] = 'stdint.h' if 'field_name' in kw: field = kw['field_name'] kw['code'] = to_header(kw) + SNIP_FIELD % {'type_name' : tu, 'field_name' : field} if not 'msg' in kw: kw['msg'] = 'Checking for field %s in %s' % (field, tu) if not 'define_name' in kw: kw['define_name'] = self.have_define((tu + '_' + field).upper()) else: kw['code'] = to_header(kw) + SNIP_TYPE % {'type_name' : tu} if not 'msg' in kw: kw['msg'] = 'Checking for type %s' % tu if not 'define_name' in kw: kw['define_name'] = self.have_define(tu.upper()) elif 'header_name' in kw: if not 'msg' in kw: kw['msg'] = 'Checking for header %s' % kw['header_name'] l = Utils.to_list(kw['header_name']) assert len(l)>0, 'list of headers in header_name is empty' kw['code'] = to_header(kw) + SNIP_EMPTY_PROGRAM if not 'uselib_store' in kw: kw['uselib_store'] = l[0].upper() if not 'define_name' in kw: kw['define_name'] = self.have_define(l[0]) if 'lib' in kw: if not 'msg' in kw: kw['msg'] = 'Checking for library %s' % kw['lib'] if not 'uselib_store' in kw: kw['uselib_store'] = kw['lib'].upper() if 'stlib' in kw: if not 'msg' in kw: kw['msg'] = 'Checking for static library %s' % kw['stlib'] if not 'uselib_store' in kw: kw['uselib_store'] = kw['stlib'].upper() if 'fragment' in kw: # an additional code fragment may be provided to replace the predefined code # in custom headers kw['code'] = kw['fragment'] if not 'msg' in kw: kw['msg'] = 'Checking for code snippet' if not 'errmsg' in kw: kw['errmsg'] = 'no' for (flagsname,flagstype) in (('cxxflags','compiler'), ('cflags','compiler'), ('linkflags','linker')): if flagsname in kw: if not 'msg' in kw: kw['msg'] = 'Checking for %s flags %s' % (flagstype, kw[flagsname]) if not 'errmsg' in kw: kw['errmsg'] = 'no' if not 'execute' in kw: kw['execute'] = False if kw['execute']: kw['features'].append('test_exec') kw['chmod'] = 493 if not 'errmsg' in kw: kw['errmsg'] = 'not found' if not 'okmsg' in kw: kw['okmsg'] = 'yes' if not 'code' in kw: kw['code'] = SNIP_EMPTY_PROGRAM # if there are headers to append automatically to the next tests if self.env[INCKEYS]: kw['code'] = '\n'.join(['#include <%s>' % x for x in self.env[INCKEYS]]) + '\n' + kw['code'] # in case defines lead to very long command-lines if kw.get('merge_config_header', False) or env.merge_config_header: kw['code'] = '%s\n\n%s' % (self.get_config_header(), kw['code']) env.DEFINES = [] # modify the copy if not kw.get('success'): kw['success'] = None if 'define_name' in kw: self.undefine(kw['define_name']) if not 'msg' in kw: self.fatal('missing "msg" in conf.check(...)') @conf def post_check(self, *k, **kw): "Set the variables after a test executed in :py:func:`waflib.Tools.c_config.check` was run successfully" is_success = 0 if kw['execute']: if kw['success'] is not None: if kw.get('define_ret', False): is_success = kw['success'] else: is_success = (kw['success'] == 0) else: is_success = (kw['success'] == 0) if 'define_name' in kw: # TODO simplify! if 'header_name' in kw or 'function_name' in kw or 'type_name' in kw or 'fragment' in kw: if kw['execute'] and kw.get('define_ret', None) and isinstance(is_success, str): self.define(kw['define_name'], is_success, quote=kw.get('quote', 1)) else: self.define_cond(kw['define_name'], is_success) else: self.define_cond(kw['define_name'], is_success) # consistency with check_cfg if kw.get('global_define', None): self.env[kw['define_name']] = is_success if 'header_name' in kw: if kw.get('auto_add_header_name', False): self.env.append_value(INCKEYS, Utils.to_list(kw['header_name'])) if is_success and 'uselib_store' in kw: from waflib.Tools import ccroot # TODO see get_uselib_vars from ccroot.py _vars = set([]) for x in kw['features']: if x in ccroot.USELIB_VARS: _vars |= ccroot.USELIB_VARS[x] for k in _vars: lk = k.lower() if lk in kw: val = kw[lk] # remove trailing slash if isinstance(val, str): val = val.rstrip(os.path.sep) self.env.append_unique(k + '_' + kw['uselib_store'], Utils.to_list(val)) return is_success @conf def check(self, *k, **kw): """ Perform a configuration test by calling :py:func:`waflib.Configure.run_build`. For the complete list of parameters, see :py:func:`waflib.Tools.c_config.validate_c`. To force a specific compiler, pass "compiler='c'" or "compiler='cxx'" in the arguments Besides build targets, complete builds can be given though a build function. All files will be written to a temporary directory:: def build(bld): lib_node = bld.srcnode.make_node('libdir/liblc1.c') lib_node.parent.mkdir() lib_node.write('#include \\nint lib_func(void) { FILE *f = fopen("foo", "r");}\\n', 'w') bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc') conf.check(build_fun=build, msg=msg) """ self.validate_c(kw) self.start_msg(kw['msg'], **kw) ret = None try: ret = self.run_build(*k, **kw) except self.errors.ConfigurationError: self.end_msg(kw['errmsg'], 'YELLOW', **kw) if Logs.verbose > 1: raise else: self.fatal('The configuration failed') else: kw['success'] = ret ret = self.post_check(*k, **kw) if not ret: self.end_msg(kw['errmsg'], 'YELLOW', **kw) self.fatal('The configuration failed %r' % ret) else: self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) return ret class test_exec(Task.Task): """ A task for executing a programs after they are built. See :py:func:`waflib.Tools.c_config.test_exec_fun`. """ color = 'PINK' def run(self): if getattr(self.generator, 'rpath', None): if getattr(self.generator, 'define_ret', False): self.generator.bld.retval = self.generator.bld.cmd_and_log([self.inputs[0].abspath()]) else: self.generator.bld.retval = self.generator.bld.exec_command([self.inputs[0].abspath()]) else: env = self.env.env or {} env.update(dict(os.environ)) for var in ('LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'PATH'): env[var] = self.inputs[0].parent.abspath() + os.path.pathsep + env.get(var, '') if getattr(self.generator, 'define_ret', False): self.generator.bld.retval = self.generator.bld.cmd_and_log([self.inputs[0].abspath()], env=env) else: self.generator.bld.retval = self.generator.bld.exec_command([self.inputs[0].abspath()], env=env) @feature('test_exec') @after_method('apply_link') def test_exec_fun(self): """ The feature **test_exec** is used to create a task that will to execute the binary created (link task output) during the build. The exit status will be set on the build context, so only one program may have the feature *test_exec*. This is used by configuration tests:: def configure(conf): conf.check(execute=True) """ self.create_task('test_exec', self.link_task.outputs[0]) @conf def check_cxx(self, *k, **kw): # DO NOT USE kw['compiler'] = 'cxx' return self.check(*k, **kw) @conf def check_cc(self, *k, **kw): # DO NOT USE kw['compiler'] = 'c' return self.check(*k, **kw) @conf def define(self, key, val, quote=True): """ Store a single define and its state into conf.env.DEFINES. If the value is True, False or None it is cast to 1 or 0. :param key: define name :type key: string :param val: value :type val: int or string :param quote: enclose strings in quotes (yes by default) :type quote: bool """ assert key and isinstance(key, str) if val is True: val = 1 elif val in (False, None): val = 0 if isinstance(val, int) or isinstance(val, float): s = '%s=%s' else: s = quote and '%s="%s"' or '%s=%s' app = s % (key, str(val)) ban = key + '=' lst = self.env['DEFINES'] for x in lst: if x.startswith(ban): lst[lst.index(x)] = app break else: self.env.append_value('DEFINES', app) self.env.append_unique(DEFKEYS, key) @conf def undefine(self, key): """ Remove a define from conf.env.DEFINES :param key: define name :type key: string """ assert key and isinstance(key, str) ban = key + '=' lst = [x for x in self.env['DEFINES'] if not x.startswith(ban)] self.env['DEFINES'] = lst self.env.append_unique(DEFKEYS, key) @conf def define_cond(self, key, val): """ Conditionally define a name:: def configure(conf): conf.define_cond('A', True) # equivalent to: # if val: conf.define('A', 1) # else: conf.undefine('A') :param key: define name :type key: string :param val: value :type val: int or string """ assert key and isinstance(key, str) if val: self.define(key, 1) else: self.undefine(key) @conf def is_defined(self, key): """ :param key: define name :type key: string :return: True if the define is set :rtype: bool """ assert key and isinstance(key, str) ban = key + '=' for x in self.env['DEFINES']: if x.startswith(ban): return True return False @conf def get_define(self, key): """ :param key: define name :type key: string :return: the value of a previously stored define or None if it is not set """ assert key and isinstance(key, str) ban = key + '=' for x in self.env['DEFINES']: if x.startswith(ban): return x[len(ban):] return None @conf def have_define(self, key): """ :param key: define name :type key: string :return: the input key prefixed by *HAVE_* and substitute any invalid characters. :rtype: string """ return (self.env.HAVE_PAT or 'HAVE_%s') % Utils.quote_define_name(key) @conf def write_config_header(self, configfile='', guard='', top=False, defines=True, headers=False, remove=True, define_prefix=''): """ Write a configuration header containing defines and includes:: def configure(cnf): cnf.define('A', 1) cnf.write_config_header('config.h') This function only adds include guards (if necessary), consult :py:func:`waflib.Tools.c_config.get_config_header` for details on the body. :param configfile: path to the file to create (relative or absolute) :type configfile: string :param guard: include guard name to add, by default it is computed from the file name :type guard: string :param top: write the configuration header from the build directory (default is from the current path) :type top: bool :param defines: add the defines (yes by default) :type defines: bool :param headers: add #include in the file :type headers: bool :param remove: remove the defines after they are added (yes by default, works like in autoconf) :type remove: bool :type define_prefix: string :param define_prefix: prefix all the defines in the file with a particular prefix """ if not configfile: configfile = WAF_CONFIG_H waf_guard = guard or 'W_%s_WAF' % Utils.quote_define_name(configfile) node = top and self.bldnode or self.path.get_bld() node = node.make_node(configfile) node.parent.mkdir() lst = ['/* WARNING! All changes made to this file will be lost! */\n'] lst.append('#ifndef %s\n#define %s\n' % (waf_guard, waf_guard)) lst.append(self.get_config_header(defines, headers, define_prefix=define_prefix)) lst.append('\n#endif /* %s */\n' % waf_guard) node.write('\n'.join(lst)) # config files must not be removed on "waf clean" self.env.append_unique(Build.CFG_FILES, [node.abspath()]) if remove: for key in self.env[DEFKEYS]: self.undefine(key) self.env[DEFKEYS] = [] @conf def get_config_header(self, defines=True, headers=False, define_prefix=''): """ Create the contents of a ``config.h`` file from the defines and includes set in conf.env.define_key / conf.env.include_key. No include guards are added. A prelude will be added from the variable env.WAF_CONFIG_H_PRELUDE if provided. This can be used to insert complex macros or include guards:: def configure(conf): conf.env.WAF_CONFIG_H_PRELUDE = '#include \\n' conf.write_config_header('config.h') :param defines: write the defines values :type defines: bool :param headers: write include entries for each element in self.env.INCKEYS :type headers: bool :type define_prefix: string :param define_prefix: prefix all the defines with a particular prefix :return: the contents of a ``config.h`` file :rtype: string """ lst = [] if self.env.WAF_CONFIG_H_PRELUDE: lst.append(self.env.WAF_CONFIG_H_PRELUDE) if headers: for x in self.env[INCKEYS]: lst.append('#include <%s>' % x) if defines: tbl = {} for k in self.env['DEFINES']: a, _, b = k.partition('=') tbl[a] = b for k in self.env[DEFKEYS]: try: txt = '#define %s%s %s' % (define_prefix, k, tbl[k]) except KeyError: txt = '/* #undef %s%s */' % (define_prefix, k) lst.append(txt) return "\n".join(lst) @conf def cc_add_flags(conf): """ Add CFLAGS / CPPFLAGS from os.environ to conf.env """ conf.add_os_flags('CPPFLAGS', dup=False) conf.add_os_flags('CFLAGS', dup=False) @conf def cxx_add_flags(conf): """ Add CXXFLAGS / CPPFLAGS from os.environ to conf.env """ conf.add_os_flags('CPPFLAGS', dup=False) conf.add_os_flags('CXXFLAGS', dup=False) @conf def link_add_flags(conf): """ Add LINKFLAGS / LDFLAGS from os.environ to conf.env """ conf.add_os_flags('LINKFLAGS', dup=False) conf.add_os_flags('LDFLAGS', dup=False) @conf def cc_load_tools(conf): """ Load the c tool """ if not conf.env.DEST_OS: conf.env.DEST_OS = Utils.unversioned_sys_platform() conf.load('c') @conf def cxx_load_tools(conf): """ Load the cxx tool """ if not conf.env.DEST_OS: conf.env.DEST_OS = Utils.unversioned_sys_platform() conf.load('cxx') @conf def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): """ Run the preprocessor to determine the compiler version The variables CC_VERSION, DEST_OS, DEST_BINFMT and DEST_CPU will be set in *conf.env* """ cmd = cc + ['-dM', '-E', '-'] env = conf.env.env or None try: out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), env=env) except Exception: conf.fatal('Could not determine the compiler version %r' % cmd) if gcc: if out.find('__INTEL_COMPILER') >= 0: conf.fatal('The intel compiler pretends to be gcc') if out.find('__GNUC__') < 0 and out.find('__clang__') < 0: conf.fatal('Could not determine the compiler type') if icc and out.find('__INTEL_COMPILER') < 0: conf.fatal('Not icc/icpc') if clang and out.find('__clang__') < 0: conf.fatal('Not clang/clang++') if not clang and out.find('__clang__') >= 0: conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure') k = {} if icc or gcc or clang: out = out.splitlines() for line in out: lst = shlex.split(line) if len(lst)>2: key = lst[1] val = lst[2] k[key] = val def isD(var): return var in k # Some documentation is available at http://predef.sourceforge.net # The names given to DEST_OS must match what Utils.unversioned_sys_platform() returns. if not conf.env.DEST_OS: conf.env.DEST_OS = '' for i in MACRO_TO_DESTOS: if isD(i): conf.env.DEST_OS = MACRO_TO_DESTOS[i] break else: if isD('__APPLE__') and isD('__MACH__'): conf.env.DEST_OS = 'darwin' elif isD('__unix__'): # unix must be tested last as it's a generic fallback conf.env.DEST_OS = 'generic' if isD('__ELF__'): conf.env.DEST_BINFMT = 'elf' elif isD('__WINNT__') or isD('__CYGWIN__') or isD('_WIN32'): conf.env.DEST_BINFMT = 'pe' conf.env.LIBDIR = conf.env.BINDIR elif isD('__APPLE__'): conf.env.DEST_BINFMT = 'mac-o' if not conf.env.DEST_BINFMT: # Infer the binary format from the os name. conf.env.DEST_BINFMT = Utils.destos_to_binfmt(conf.env.DEST_OS) for i in MACRO_TO_DEST_CPU: if isD(i): conf.env.DEST_CPU = MACRO_TO_DEST_CPU[i] break Logs.debug('ccroot: dest platform: ' + ' '.join([conf.env[x] or '?' for x in ('DEST_OS', 'DEST_BINFMT', 'DEST_CPU')])) if icc: ver = k['__INTEL_COMPILER'] conf.env['CC_VERSION'] = (ver[:-2], ver[-2], ver[-1]) else: if isD('__clang__') and isD('__clang_major__'): conf.env['CC_VERSION'] = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) else: # older clang versions and gcc conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k.get('__GNUC_PATCHLEVEL__', '0')) return k @conf def get_xlc_version(conf, cc): """Get the compiler version""" cmd = cc + ['-qversion'] try: out, err = conf.cmd_and_log(cmd, output=0) except Errors.WafError: conf.fatal('Could not find xlc %r' % cmd) # the intention is to catch the 8.0 in "IBM XL C/C++ Enterprise Edition V8.0 for AIX..." for v in (r"IBM XL C/C\+\+.* V(?P\d*)\.(?P\d*)",): version_re = re.compile(v, re.I).search match = version_re(out or err) if match: k = match.groupdict() conf.env['CC_VERSION'] = (k['major'], k['minor']) break else: conf.fatal('Could not determine the XLC version.') @conf def get_suncc_version(conf, cc): """Get the compiler version""" cmd = cc + ['-V'] try: out, err = conf.cmd_and_log(cmd, output=0) except Errors.WafError as e: # Older versions of the compiler exit with non-zero status when reporting their version if not (hasattr(e, 'returncode') and hasattr(e, 'stdout') and hasattr(e, 'stderr')): conf.fatal('Could not find suncc %r' % cmd) out = e.stdout err = e.stderr version = (out or err) version = version.splitlines()[0] version_re = re.compile(r'cc:\s+sun\s+(c\+\+|c)\s+(?P\d*)\.(?P\d*)', re.I).search match = version_re(version) if match: k = match.groupdict() conf.env['CC_VERSION'] = (k['major'], k['minor']) else: conf.fatal('Could not determine the suncc version.') # ============ the --as-needed flag should added during the configuration, not at runtime ========= @conf def add_as_needed(self): """ Add ``--as-needed`` to the *LINKFLAGS* On some platforms, it is a default flag. In some cases (e.g., in NS-3) it is necessary to explicitly disable this feature with `-Wl,--no-as-needed` flag. """ if self.env.DEST_BINFMT == 'elf' and 'gcc' in (self.env.CXX_NAME, self.env.CC_NAME): self.env.append_unique('LINKFLAGS', '-Wl,--as-needed') # ============ parallel configuration class cfgtask(Task.TaskBase): """ A task that executes configuration tests make sure that the checks write to conf.env in a thread-safe manner for the moment it only executes conf.check """ def display(self): return '' def runnable_status(self): return Task.RUN_ME def uid(self): return Utils.SIG_NIL def run(self): conf = self.conf bld = Build.BuildContext(top_dir=conf.srcnode.abspath(), out_dir=conf.bldnode.abspath()) bld.env = conf.env bld.init_dirs() bld.in_msg = 1 # suppress top-level start_msg bld.logger = self.logger try: bld.check(**self.args) except Exception: return 1 @conf def multicheck(self, *k, **kw): """ Use tuples to perform parallel configuration tests """ self.start_msg(kw.get('msg', 'Executing %d configuration tests' % len(k)), **kw) class par(object): def __init__(self): self.keep = False self.returned_tasks = [] self.task_sigs = {} self.progress_bar = 0 def total(self): return len(tasks) def to_log(self, *k, **kw): return bld = par() tasks = [] for dct in k: x = cfgtask(bld=bld) tasks.append(x) x.args = dct x.bld = bld x.conf = self x.args = dct # bind a logger that will keep the info in memory x.logger = Logs.make_mem_logger(str(id(x)), self.logger) def it(): yield tasks while 1: yield [] p = Runner.Parallel(bld, Options.options.jobs) p.biter = it() p.start() # flush the logs in order into the config.log for x in tasks: x.logger.memhandler.flush() if p.error: for x in p.error: if getattr(x, 'err_msg', None): self.to_log(x.err_msg) self.end_msg('fail', color='RED') raise Errors.WafError('There is an error in the library, read config.log for more information') for x in tasks: if x.hasrun != Task.SUCCESS: self.end_msg(kw.get('errmsg', 'no'), color='YELLOW', **kw) self.fatal(kw.get('fatalmsg', None) or 'One of the tests has failed, read config.log for more information') self.end_msg('ok', **kw) 1.9.12~dfsg/waflib/Tools/gcc.py0000644000000000000000000001021013214314510015004 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) # Yinon Ehrlich, 2009 """ gcc/llvm detection. """ from waflib.Tools import ccroot, ar from waflib.Configure import conf @conf def find_gcc(conf): """ Find the program gcc, and if present, try to detect its version number """ cc = conf.find_program(['gcc', 'cc'], var='CC') conf.get_cc_version(cc, gcc=True) conf.env.CC_NAME = 'gcc' @conf def gcc_common_flags(conf): """ Common flags for gcc on nearly all platforms """ v = conf.env v['CC_SRC_F'] = [] v['CC_TGT_F'] = ['-c', '-o'] # linker if not v['LINK_CC']: v['LINK_CC'] = v['CC'] v['CCLNK_SRC_F'] = [] v['CCLNK_TGT_F'] = ['-o'] v['CPPPATH_ST'] = '-I%s' v['DEFINES_ST'] = '-D%s' v['LIB_ST'] = '-l%s' # template for adding libs v['LIBPATH_ST'] = '-L%s' # template for adding libpaths v['STLIB_ST'] = '-l%s' v['STLIBPATH_ST'] = '-L%s' v['RPATH_ST'] = '-Wl,-rpath,%s' v['SONAME_ST'] = '-Wl,-h,%s' v['SHLIB_MARKER'] = '-Wl,-Bdynamic' v['STLIB_MARKER'] = '-Wl,-Bstatic' # program v['cprogram_PATTERN'] = '%s' # shared librar v['CFLAGS_cshlib'] = ['-fPIC'] v['LINKFLAGS_cshlib'] = ['-shared'] v['cshlib_PATTERN'] = 'lib%s.so' # static lib v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic'] v['cstlib_PATTERN'] = 'lib%s.a' # osx stuff v['LINKFLAGS_MACBUNDLE'] = ['-bundle', '-undefined', 'dynamic_lookup'] v['CFLAGS_MACBUNDLE'] = ['-fPIC'] v['macbundle_PATTERN'] = '%s.bundle' @conf def gcc_modifier_win32(conf): """Configuration flags for executing gcc on Windows""" v = conf.env v['cprogram_PATTERN'] = '%s.exe' v['cshlib_PATTERN'] = '%s.dll' v['implib_PATTERN'] = 'lib%s.dll.a' v['IMPLIB_ST'] = '-Wl,--out-implib,%s' v['CFLAGS_cshlib'] = [] # Auto-import is enabled by default even without this option, # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages # that the linker emits otherwise. v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) @conf def gcc_modifier_cygwin(conf): """Configuration flags for executing gcc on Cygwin""" gcc_modifier_win32(conf) v = conf.env v['cshlib_PATTERN'] = 'cyg%s.dll' v.append_value('LINKFLAGS_cshlib', ['-Wl,--enable-auto-image-base']) v['CFLAGS_cshlib'] = [] @conf def gcc_modifier_darwin(conf): """Configuration flags for executing gcc on MacOS""" v = conf.env v['CFLAGS_cshlib'] = ['-fPIC'] v['LINKFLAGS_cshlib'] = ['-dynamiclib'] v['cshlib_PATTERN'] = 'lib%s.dylib' v['FRAMEWORKPATH_ST'] = '-F%s' v['FRAMEWORK_ST'] = ['-framework'] v['ARCH_ST'] = ['-arch'] v['LINKFLAGS_cstlib'] = [] v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] v['SONAME_ST'] = [] @conf def gcc_modifier_aix(conf): """Configuration flags for executing gcc on AIX""" v = conf.env v['LINKFLAGS_cprogram'] = ['-Wl,-brtl'] v['LINKFLAGS_cshlib'] = ['-shared','-Wl,-brtl,-bexpfull'] v['SHLIB_MARKER'] = [] @conf def gcc_modifier_hpux(conf): v = conf.env v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] v['CFLAGS_cshlib'] = ['-fPIC','-DPIC'] v['cshlib_PATTERN'] = 'lib%s.sl' @conf def gcc_modifier_openbsd(conf): conf.env.SONAME_ST = [] @conf def gcc_modifier_osf1V(conf): v = conf.env v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] v['SONAME_ST'] = [] @conf def gcc_modifier_platform(conf): """Execute platform-specific functions based on *gcc_modifier_+NAME*""" # * set configurations specific for a platform. # * the destination platform is detected automatically by looking at the macros the compiler predefines, # and if it's not recognised, it fallbacks to sys.platform. gcc_modifier_func = getattr(conf, 'gcc_modifier_' + conf.env.DEST_OS, None) if gcc_modifier_func: gcc_modifier_func() def configure(conf): """ Configuration for gcc """ conf.find_gcc() conf.find_ar() conf.gcc_common_flags() conf.gcc_modifier_platform() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/Task.py0000644000000000000000000010250713214314510014065 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ Tasks represent atomic operations such as processes. """ import os, re, sys from waflib import Utils, Logs, Errors # task states NOT_RUN = 0 """The task was not executed yet""" MISSING = 1 """The task has been executed but the files have not been created""" CRASHED = 2 """The task execution returned a non-zero exit status""" EXCEPTION = 3 """An exception occured in the task execution""" SKIPPED = 8 """The task did not have to be executed""" SUCCESS = 9 """The task was successfully executed""" ASK_LATER = -1 """The task is not ready to be executed""" SKIP_ME = -2 """The task does not need to be executed""" RUN_ME = -3 """The task must be executed""" # To save some memory during the build, consider discarding tsk.last_cmd in the two templates below COMPILE_TEMPLATE_SHELL = ''' def f(tsk): env = tsk.env gen = tsk.generator bld = gen.bld cwdx = getattr(bld, 'cwdx', bld.bldnode) # TODO single cwd value in waf 1.9 wd = getattr(tsk, 'cwd', None) p = env.get_flat tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s return tsk.exec_command(cmd, cwd=wd, env=env.env or None) ''' COMPILE_TEMPLATE_NOSHELL = ''' def f(tsk): env = tsk.env gen = tsk.generator bld = gen.bld cwdx = getattr(bld, 'cwdx', bld.bldnode) # TODO single cwd value in waf 1.9 wd = getattr(tsk, 'cwd', None) def to_list(xx): if isinstance(xx, str): return [xx] return xx tsk.last_cmd = lst = [] %s lst = [x for x in lst if x] return tsk.exec_command(lst, cwd=wd, env=env.env or None) ''' classes = {} "Class tasks created by user scripts or Waf tools (maps names to class objects). Task classes defined in Waf tools are registered here through the metaclass :py:class:`waflib.Task.store_task_type`." class store_task_type(type): """ Metaclass: store the task classes into :py:const:`waflib.Task.classes`, or to the dict pointed by the class attribute 'register'. The attribute 'run_str' will be processed to compute a method 'run' on the task class The decorator :py:func:`waflib.Task.cache_outputs` is also applied to the class """ def __init__(cls, name, bases, dict): super(store_task_type, cls).__init__(name, bases, dict) name = cls.__name__ if name.endswith('_task'): name = name.replace('_task', '') if name != 'evil' and name != 'TaskBase': global classes if getattr(cls, 'run_str', None): # if a string is provided, convert it to a method (f, dvars) = compile_fun(cls.run_str, cls.shell) cls.hcode = Utils.h_cmd(cls.run_str) cls.orig_run_str = cls.run_str # change the name of run_str or it is impossible to subclass with a function cls.run_str = None cls.run = f cls.vars = list(set(cls.vars + dvars)) cls.vars.sort() elif getattr(cls, 'run', None) and not 'hcode' in cls.__dict__: # getattr(cls, 'hcode') would look in the upper classes cls.hcode = Utils.h_cmd(cls.run) # be creative getattr(cls, 'register', classes)[name] = cls evil = store_task_type('evil', (object,), {}) "Base class provided to avoid writing a metaclass, so the code can run in python 2.6 and 3.x unmodified" class TaskBase(evil): """ Base class for all Waf tasks, which should be seen as an interface. For illustration purposes, instances of this class will execute the attribute 'fun' in :py:meth:`waflib.Task.TaskBase.run`. When in doubt, create subclasses of :py:class:`waflib.Task.Task` instead. Subclasses should override these methods: #. __str__: string to display to the user #. runnable_status: ask the task if it should be run, skipped, or if we have to ask later #. run: let threads execute the task #. post_run: let threads update the data regarding the task (cache) .. warning:: For backward compatibility reasons, the suffix "_task" is truncated in derived class names. This limitation will be removed in Waf 1.9. """ color = 'GREEN' """Color for the console display, see :py:const:`waflib.Logs.colors_lst`""" ext_in = [] """File extensions that objects of this task class might use""" ext_out = [] """File extensions that objects of this task class might create""" before = [] """List of task class names to execute before instances of this class""" after = [] """List of task class names to execute after instances of this class""" hcode = '' """String representing an additional hash for the class representation""" def __init__(self, *k, **kw): """ The base task class requires a task generator, which will be itself if missing """ self.hasrun = NOT_RUN try: self.generator = kw['generator'] except KeyError: self.generator = self def __repr__(self): "for debugging purposes" return '\n\t{task %r: %s %s}' % (self.__class__.__name__, id(self), str(getattr(self, 'fun', ''))) def __str__(self): "string to display to the user" if hasattr(self, 'fun'): return self.fun.__name__ return self.__class__.__name__ def __hash__(self): "Very fast hashing scheme but not persistent (replace/implement in subclasses and see :py:meth:`waflib.Task.Task.uid`)" return id(self) def keyword(self): if hasattr(self, 'fun'): return 'Function' return 'Processing' def exec_command(self, cmd, **kw): """ Wrapper for :py:meth:`waflib.Context.Context.exec_command` which sets a current working directory to ``build.variant_dir`` :return: the return code :rtype: int """ bld = self.generator.bld try: if not kw.get('cwd', None): kw['cwd'] = bld.cwd except AttributeError: bld.cwd = kw['cwd'] = bld.variant_dir return bld.exec_command(cmd, **kw) def runnable_status(self): """ State of the task :return: a task state in :py:const:`waflib.Task.RUN_ME`, :py:const:`waflib.Task.SKIP_ME` or :py:const:`waflib.Task.ASK_LATER`. :rtype: int """ return RUN_ME def process(self): """ Assume that the task has had a new attribute ``master`` which is an instance of :py:class:`waflib.Runner.Parallel`. Execute the task and then put it back in the queue :py:attr:`waflib.Runner.Parallel.out` (may be replaced by subclassing). """ m = self.master if m.stop: m.out.put(self) return # remove the task signature immediately before it is executed # in case of failure the task will be executed again try: # TODO waf 1.9 - this breaks encapsulation del self.generator.bld.task_sigs[self.uid()] except KeyError: pass try: self.generator.bld.returned_tasks.append(self) self.log_display(self.generator.bld) ret = self.run() except Exception: self.err_msg = Utils.ex_stack() self.hasrun = EXCEPTION # TODO cleanup m.error_handler(self) m.out.put(self) return if ret: self.err_code = ret self.hasrun = CRASHED else: try: self.post_run() except Errors.WafError: pass except Exception: self.err_msg = Utils.ex_stack() self.hasrun = EXCEPTION else: self.hasrun = SUCCESS if self.hasrun != SUCCESS: m.error_handler(self) m.out.put(self) def run(self): """ Called by threads to execute the tasks. The default is empty and meant to be overridden in subclasses. It is a bad idea to create nodes in this method (so, no node.ant_glob) :rtype: int """ if hasattr(self, 'fun'): return self.fun(self) return 0 def post_run(self): "Update the cache files (executed by threads). Override in subclasses." pass def log_display(self, bld): "Write the execution status on the context logger" if self.generator.bld.progress_bar == 3: return s = self.display() if s: if bld.logger: logger = bld.logger else: logger = Logs if self.generator.bld.progress_bar == 1: c1 = Logs.colors.cursor_off c2 = Logs.colors.cursor_on logger.info(s, extra={'stream': sys.stderr, 'terminator':'', 'c1': c1, 'c2' : c2}) else: logger.info(s, extra={'terminator':'', 'c1': '', 'c2' : ''}) def display(self): """ Return an execution status for the console, the progress bar, or the IDE output. :rtype: string """ col1 = Logs.colors(self.color) col2 = Logs.colors.NORMAL master = self.master def cur(): # the current task position, computed as late as possible tmp = -1 if hasattr(master, 'ready'): tmp -= master.ready.qsize() return master.processed + tmp if self.generator.bld.progress_bar == 1: return self.generator.bld.progress_line(cur(), master.total, col1, col2) if self.generator.bld.progress_bar == 2: ela = str(self.generator.bld.timer) try: ins = ','.join([n.name for n in self.inputs]) except AttributeError: ins = '' try: outs = ','.join([n.name for n in self.outputs]) except AttributeError: outs = '' return '|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n' % (master.total, cur(), ins, outs, ela) s = str(self) if not s: return None total = master.total n = len(str(total)) fs = '[%%%dd/%%%dd] %%s%%s%%s%%s\n' % (n, n) kw = self.keyword() if kw: kw += ' ' return fs % (cur(), total, kw, col1, s, col2) def attr(self, att, default=None): """ Retrieve an attribute from the instance or from the class. :param att: variable name :type att: string :param default: default value """ ret = getattr(self, att, self) if ret is self: return getattr(self.__class__, att, default) return ret def hash_constraints(self): """ Identify a task type for all the constraints relevant for the scheduler: precedence, file production :return: a hash value :rtype: string """ cls = self.__class__ tup = (str(cls.before), str(cls.after), str(cls.ext_in), str(cls.ext_out), cls.__name__, cls.hcode) h = hash(tup) return h def format_error(self): """ Error message to display to the user when a build fails :rtype: string """ msg = getattr(self, 'last_cmd', '') name = getattr(self.generator, 'name', '') if getattr(self, "err_msg", None): return self.err_msg elif not self.hasrun: return 'task in %r was not executed for some reason: %r' % (name, self) elif self.hasrun == CRASHED: try: return ' -> task in %r failed (exit status %r): %r\n%r' % (name, self.err_code, self, msg) except AttributeError: return ' -> task in %r failed: %r\n%r' % (name, self, msg) elif self.hasrun == MISSING: return ' -> missing files in %r: %r\n%r' % (name, self, msg) else: return 'invalid status for task in %r: %r' % (name, self.hasrun) def colon(self, var1, var2): """ Support code for scriptlet expressions such as ${FOO_ST:FOO} If the first variable (FOO_ST) is empty, then an empty list is returned The results will be slightly different if FOO_ST is a list, for example:: env.FOO_ST = ['-a', '-b'] env.FOO_ST = '-I%s' # ${FOO_ST:FOO} returns ['-Ip1', '-Ip2'] env.FOO = ['p1', 'p2'] # ${FOO_ST:FOO} returns ['-a', '-b', 'p1', '-a', '-b', 'p2'] """ tmp = self.env[var1] if not tmp: return [] if isinstance(var2, str): it = self.env[var2] else: it = var2 if isinstance(tmp, str): return [tmp % x for x in it] else: lst = [] for y in it: lst.extend(tmp) lst.append(y) return lst class Task(TaskBase): """ This class deals with the filesystem (:py:class:`waflib.Node.Node`). The method :py:class:`waflib.Task.Task.runnable_status` uses a hash value (from :py:class:`waflib.Task.Task.signature`) which is persistent from build to build. When the value changes, the task has to be executed. The method :py:class:`waflib.Task.Task.post_run` will assign the task signature to the output nodes (if present). .. warning:: For backward compatibility reasons, the suffix "_task" is truncated in derived class names. This limitation will be removed in Waf 1.9. """ vars = [] """Variables to depend on (class attribute used for :py:meth:`waflib.Task.Task.sig_vars`)""" shell = False """Execute the command with the shell (class attribute)""" def __init__(self, *k, **kw): TaskBase.__init__(self, *k, **kw) self.env = kw['env'] """ConfigSet object (make sure to provide one)""" self.inputs = [] """List of input nodes, which represent the files used by the task instance""" self.outputs = [] """List of output nodes, which represent the files created by the task instance""" self.dep_nodes = [] """List of additional nodes to depend on""" self.run_after = set([]) """Set of tasks that must be executed before this one""" # Additionally, you may define the following #self.dep_vars = 'PREFIX DATADIR' def __str__(self): "string to display to the user" name = self.__class__.__name__ if self.outputs: if (name.endswith('lib') or name.endswith('program')) or not self.inputs: node = self.outputs[0] return node.path_from(node.ctx.launch_node()) if not (self.inputs or self.outputs): return self.__class__.__name__ if len(self.inputs) == 1: node = self.inputs[0] return node.path_from(node.ctx.launch_node()) src_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.inputs]) tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs]) if self.outputs: sep = ' -> ' else: sep = '' return '%s: %s%s%s' % (self.__class__.__name__.replace('_task', ''), src_str, sep, tgt_str) def keyword(self): name = self.__class__.__name__ if name.endswith('lib') or name.endswith('program'): return 'Linking' if len(self.inputs) == 1 and len(self.outputs) == 1: return 'Compiling' if not self.inputs: if self.outputs: return 'Creating' else: return 'Running' return 'Processing' def __repr__(self): "for debugging purposes" try: ins = ",".join([x.name for x in self.inputs]) outs = ",".join([x.name for x in self.outputs]) except AttributeError: ins = ",".join([str(x) for x in self.inputs]) outs = ",".join([str(x) for x in self.outputs]) return "".join(['\n\t{task %r: ' % id(self), self.__class__.__name__, " ", ins, " -> ", outs, '}']) def uid(self): """ Return an identifier used to determine if tasks are up-to-date. Since the identifier will be stored between executions, it must be: - unique: no two tasks return the same value (for a given build context) - the same for a given task instance By default, the node paths, the class name, and the function are used as inputs to compute a hash. The pointer to the object (python built-in 'id') will change between build executions, and must be avoided in such hashes. :return: hash value :rtype: string """ try: return self.uid_ except AttributeError: m = Utils.md5() up = m.update up(self.__class__.__name__) for x in self.inputs + self.outputs: up(x.abspath()) self.uid_ = m.digest() return self.uid_ def set_inputs(self, inp): """ Append the nodes to the *inputs* :param inp: input nodes :type inp: node or list of nodes """ if isinstance(inp, list): self.inputs += inp else: self.inputs.append(inp) def set_outputs(self, out): """ Append the nodes to the *outputs* :param out: output nodes :type out: node or list of nodes """ if isinstance(out, list): self.outputs += out else: self.outputs.append(out) def set_run_after(self, task): """ Run this task only after *task*. Affect :py:meth:`waflib.Task.runnable_status` You probably want to use tsk.run_after.add(task) directly :param task: task :type task: :py:class:`waflib.Task.Task` """ assert isinstance(task, TaskBase) self.run_after.add(task) def signature(self): """ Task signatures are stored between build executions, they are use to track the changes made to the input nodes (not to the outputs!). The signature hashes data from various sources: * explicit dependencies: files listed in the inputs (list of node objects) :py:meth:`waflib.Task.Task.sig_explicit_deps` * implicit dependencies: list of nodes returned by scanner methods (when present) :py:meth:`waflib.Task.Task.sig_implicit_deps` * hashed data: variables/values read from task.__class__.vars/task.env :py:meth:`waflib.Task.Task.sig_vars` If the signature is expected to give a different result, clear the cache kept in ``self.cache_sig``:: from waflib import Task class cls(Task.Task): def signature(self): sig = super(Task.Task, self).signature() delattr(self, 'cache_sig') return super(Task.Task, self).signature() """ try: return self.cache_sig except AttributeError: pass self.m = Utils.md5() self.m.update(self.hcode) # explicit deps self.sig_explicit_deps() # env vars self.sig_vars() # implicit deps / scanner results if self.scan: try: self.sig_implicit_deps() except Errors.TaskRescan: return self.signature() ret = self.cache_sig = self.m.digest() return ret def runnable_status(self): """ Override :py:meth:`waflib.Task.TaskBase.runnable_status` to determine if the task is ready to be run (:py:attr:`waflib.Task.Task.run_after`) """ #return 0 # benchmarking for t in self.run_after: if not t.hasrun: return ASK_LATER bld = self.generator.bld # first compute the signature try: new_sig = self.signature() except Errors.TaskNotReady: return ASK_LATER # compare the signature to a signature computed previously key = self.uid() try: prev_sig = bld.task_sigs[key] except KeyError: Logs.debug("task: task %r must run as it was never run before or the task code changed" % self) return RUN_ME # compare the signatures of the outputs for node in self.outputs: try: if node.sig != new_sig: return RUN_ME except AttributeError: Logs.debug("task: task %r must run as the output nodes do not exist" % self) return RUN_ME if new_sig != prev_sig: return RUN_ME return SKIP_ME def post_run(self): """ Called after successful execution to update the cache data :py:class:`waflib.Node.Node` sigs and :py:attr:`waflib.Build.BuildContext.task_sigs`. The node signature is obtained from the task signature, but the output nodes may also get the signature of their contents. See the class decorator :py:func:`waflib.Task.update_outputs` if you need this behaviour. """ bld = self.generator.bld sig = self.signature() for node in self.outputs: # check if the node exists .. try: os.stat(node.abspath()) except OSError: self.hasrun = MISSING self.err_msg = '-> missing file: %r' % node.abspath() raise Errors.WafError(self.err_msg) # important, store the signature for the next run node.sig = node.cache_sig = sig bld.task_sigs[self.uid()] = self.cache_sig def sig_explicit_deps(self): """ Used by :py:meth:`waflib.Task.Task.signature`, hash :py:attr:`waflib.Task.Task.inputs` and :py:attr:`waflib.Task.Task.dep_nodes` signatures. :rtype: hash value """ bld = self.generator.bld upd = self.m.update # the inputs for x in self.inputs + self.dep_nodes: try: upd(x.get_bld_sig()) except (AttributeError, TypeError): raise Errors.WafError('Missing node signature for %r (required by %r)' % (x, self)) # manual dependencies, they can slow down the builds if bld.deps_man: additional_deps = bld.deps_man for x in self.inputs + self.outputs: try: d = additional_deps[id(x)] except KeyError: continue for v in d: if isinstance(v, bld.root.__class__): try: v = v.get_bld_sig() except AttributeError: raise Errors.WafError('Missing node signature for %r (required by %r)' % (v, self)) elif hasattr(v, '__call__'): v = v() # dependency is a function, call it upd(v) return self.m.digest() def sig_vars(self): """ Used by :py:meth:`waflib.Task.Task.signature`, hash :py:attr:`waflib.Task.Task.env` variables/values :rtype: hash value """ bld = self.generator.bld env = self.env upd = self.m.update # dependencies on the environment vars act_sig = bld.hash_env_vars(env, self.__class__.vars) upd(act_sig) # additional variable dependencies, if provided dep_vars = getattr(self, 'dep_vars', None) if dep_vars: upd(bld.hash_env_vars(env, dep_vars)) return self.m.digest() scan = None """ This method, when provided, returns a tuple containing: * a list of nodes corresponding to real files * a list of names for files not found in path_lst For example:: from waflib.Task import Task class mytask(Task): def scan(self, node): return ((), ()) The first and second lists are stored in :py:attr:`waflib.Build.BuildContext.node_deps` and :py:attr:`waflib.Build.BuildContext.raw_deps` respectively. """ def sig_implicit_deps(self): """ Used by :py:meth:`waflib.Task.Task.signature` hashes node signatures obtained by scanning for dependencies (:py:meth:`waflib.Task.Task.scan`). The exception :py:class:`waflib.Errors.TaskRescan` is thrown when a file has changed. When this occurs, :py:meth:`waflib.Task.Task.signature` is called once again, and this method will be executed once again, this time calling :py:meth:`waflib.Task.Task.scan` for searching the dependencies. :rtype: hash value """ bld = self.generator.bld # get the task signatures from previous runs key = self.uid() prev = bld.task_sigs.get((key, 'imp'), []) # for issue #379 if prev: try: if prev == self.compute_sig_implicit_deps(): return prev except Errors.TaskNotReady: raise except EnvironmentError: # when a file was renamed (IOError usually), remove the stale nodes (headers in folders without source files) # this will break the order calculation for headers created during the build in the source directory (should be uncommon) # the behaviour will differ when top != out for x in bld.node_deps.get(self.uid(), []): if not x.is_bld(): try: os.stat(x.abspath()) except OSError: try: del x.parent.children[x.name] except KeyError: pass del bld.task_sigs[(key, 'imp')] raise Errors.TaskRescan('rescan') # no previous run or the signature of the dependencies has changed, rescan the dependencies (nodes, names) = self.scan() if Logs.verbose: Logs.debug('deps: scanner for %s returned %s %s' % (str(self), str(nodes), str(names))) # store the dependencies in the cache bld.node_deps[key] = nodes bld.raw_deps[key] = names # might happen self.are_implicit_nodes_ready() # recompute the signature and return it try: bld.task_sigs[(key, 'imp')] = sig = self.compute_sig_implicit_deps() except Exception: if Logs.verbose: for k in bld.node_deps.get(self.uid(), []): try: k.get_bld_sig() except Exception: Logs.warn('Missing signature for node %r (may cause rebuilds)' % k) else: return sig def compute_sig_implicit_deps(self): """ Used by :py:meth:`waflib.Task.Task.sig_implicit_deps` for computing the actual hash of the :py:class:`waflib.Node.Node` returned by the scanner. :return: hash value :rtype: string """ upd = self.m.update bld = self.generator.bld self.are_implicit_nodes_ready() # scanner returns a node that does not have a signature # just *ignore* the error and let them figure out from the compiler output # waf -k behaviour for k in bld.node_deps.get(self.uid(), []): upd(k.get_bld_sig()) return self.m.digest() def are_implicit_nodes_ready(self): """ For each node returned by the scanner, see if there is a task behind it, and force the build order The performance impact on null builds is nearly invisible (1.66s->1.86s), but this is due to agressive caching (1.86s->28s) """ bld = self.generator.bld try: cache = bld.dct_implicit_nodes except AttributeError: bld.dct_implicit_nodes = cache = {} try: dct = cache[bld.cur] except KeyError: dct = cache[bld.cur] = {} for tsk in bld.cur_tasks: for x in tsk.outputs: dct[x] = tsk modified = False for x in bld.node_deps.get(self.uid(), []): if x in dct: self.run_after.add(dct[x]) modified = True if modified: for tsk in self.run_after: if not tsk.hasrun: #print "task is not ready..." raise Errors.TaskNotReady('not ready') if sys.hexversion > 0x3000000: def uid(self): try: return self.uid_ except AttributeError: m = Utils.md5() up = m.update up(self.__class__.__name__.encode('iso8859-1', 'xmlcharrefreplace')) for x in self.inputs + self.outputs: up(x.abspath().encode('iso8859-1', 'xmlcharrefreplace')) self.uid_ = m.digest() return self.uid_ uid.__doc__ = Task.uid.__doc__ Task.uid = uid def is_before(t1, t2): """ Return a non-zero value if task t1 is to be executed before task t2:: t1.ext_out = '.h' t2.ext_in = '.h' t2.after = ['t1'] t1.before = ['t2'] waflib.Task.is_before(t1, t2) # True :param t1: task :type t1: :py:class:`waflib.Task.TaskBase` :param t2: task :type t2: :py:class:`waflib.Task.TaskBase` """ to_list = Utils.to_list for k in to_list(t2.ext_in): if k in to_list(t1.ext_out): return 1 if t1.__class__.__name__ in to_list(t2.after): return 1 if t2.__class__.__name__ in to_list(t1.before): return 1 return 0 def set_file_constraints(tasks): """ Adds tasks to the task 'run_after' attribute based on the task inputs and outputs :param tasks: tasks :type tasks: list of :py:class:`waflib.Task.TaskBase` """ ins = Utils.defaultdict(set) outs = Utils.defaultdict(set) for x in tasks: for a in getattr(x, 'inputs', []) + getattr(x, 'dep_nodes', []): ins[id(a)].add(x) for a in getattr(x, 'outputs', []): outs[id(a)].add(x) links = set(ins.keys()).intersection(outs.keys()) for k in links: for a in ins[k]: a.run_after.update(outs[k]) def set_precedence_constraints(tasks): """ Add tasks to the task 'run_after' attribute based on the after/before/ext_out/ext_in attributes :param tasks: tasks :type tasks: list of :py:class:`waflib.Task.TaskBase` """ cstr_groups = Utils.defaultdict(list) for x in tasks: h = x.hash_constraints() cstr_groups[h].append(x) keys = list(cstr_groups.keys()) maxi = len(keys) # this list should be short for i in range(maxi): t1 = cstr_groups[keys[i]][0] for j in range(i + 1, maxi): t2 = cstr_groups[keys[j]][0] # add the constraints based on the comparisons if is_before(t1, t2): a = i b = j elif is_before(t2, t1): a = j b = i else: continue aval = set(cstr_groups[keys[a]]) for x in cstr_groups[keys[b]]: x.run_after.update(aval) def funex(c): """ Compile a function by 'exec' :param c: function to compile :type c: string :return: the function 'f' declared in the input string :rtype: function """ dc = {} exec(c, dc) return dc['f'] reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P\w+)(?P.*?)\})", re.M) def compile_fun_shell(line): """ Create a compiled function to execute a process with the shell WARNING: this method may disappear anytime, so use compile_fun instead """ extr = [] def repl(match): g = match.group if g('dollar'): return "$" elif g('backslash'): return '\\\\' elif g('subst'): extr.append((g('var'), g('code'))); return "%s" return None line = reg_act.sub(repl, line) or line parm = [] dvars = [] app = parm.append for (var, meth) in extr: if var == 'SRC': if meth: app('tsk.inputs%s' % meth) else: app('" ".join([a.path_from(cwdx) for a in tsk.inputs])') elif var == 'TGT': if meth: app('tsk.outputs%s' % meth) else: app('" ".join([a.path_from(cwdx) for a in tsk.outputs])') elif meth: if meth.startswith(':'): m = meth[1:] if m == 'SRC': m = '[a.path_from(cwdx) for a in tsk.inputs]' elif m == 'TGT': m = '[a.path_from(cwdx) for a in tsk.outputs]' elif m[:3] not in ('tsk', 'gen', 'bld'): dvars.extend([var, meth[1:]]) m = '%r' % m app('" ".join(tsk.colon(%r, %s))' % (var, m)) else: app('%s%s' % (var, meth)) else: if not var in dvars: dvars.append(var) app("p('%s')" % var) if parm: parm = "%% (%s) " % (',\n\t\t'.join(parm)) else: parm = '' c = COMPILE_TEMPLATE_SHELL % (line, parm) Logs.debug('action: %s' % c.strip().splitlines()) return (funex(c), dvars) def compile_fun_noshell(line): """ Create a compiled function to execute a process without the shell WARNING: this method may disappear anytime, so use compile_fun instead """ extr = [] def repl(match): g = match.group if g('dollar'): return "$" elif g('backslash'): return '\\' elif g('subst'): extr.append((g('var'), g('code'))); return "<<|@|>>" return None line2 = reg_act.sub(repl, line) params = line2.split('<<|@|>>') assert(extr) buf = [] dvars = [] app = buf.append for x in range(len(extr)): params[x] = params[x].strip() if params[x]: app("lst.extend(%r)" % params[x].split()) (var, meth) = extr[x] if var == 'SRC': if meth: app('lst.append(tsk.inputs%s)' % meth) else: app("lst.extend([a.path_from(cwdx) for a in tsk.inputs])") elif var == 'TGT': if meth: app('lst.append(tsk.outputs%s)' % meth) else: app("lst.extend([a.path_from(cwdx) for a in tsk.outputs])") elif meth: if meth.startswith(':'): m = meth[1:] if m == 'SRC': m = '[a.path_from(cwdx) for a in tsk.inputs]' elif m == 'TGT': m = '[a.path_from(cwdx) for a in tsk.outputs]' elif m[:3] not in ('tsk', 'gen', 'bld'): dvars.extend([var, m]) m = '%r' % m app('lst.extend(tsk.colon(%r, %s))' % (var, m)) else: app('lst.extend(gen.to_list(%s%s))' % (var, meth)) else: app('lst.extend(to_list(env[%r]))' % var) if not var in dvars: dvars.append(var) if extr: if params[-1]: app("lst.extend(%r)" % params[-1].split()) fun = COMPILE_TEMPLATE_NOSHELL % "\n\t".join(buf) Logs.debug('action: %s' % fun.strip().splitlines()) return (funex(fun), dvars) def compile_fun(line, shell=False): """ Parse a string expression such as "${CC} ${SRC} -o ${TGT}" and return a pair containing: * the function created (compiled) for use as :py:meth:`waflib.Task.TaskBase.run` * the list of variables that imply a dependency from self.env for example:: from waflib.Task import compile_fun compile_fun('cxx', '${CXX} -o ${TGT[0]} ${SRC} -I ${SRC[0].parent.bldpath()}') def build(bld): bld(source='wscript', rule='echo "foo\\${SRC[0].name}\\bar"') The env variables (CXX, ..) on the task must not hold dicts (order) The reserved keywords *TGT* and *SRC* represent the task input and output nodes """ if isinstance(line, str): if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0: shell = True else: dvars_lst = [] funs_lst = [] for x in line: if isinstance(x, str): fun, dvars = compile_fun(x, shell) dvars_lst += dvars funs_lst.append(fun) else: # assume a function to let through funs_lst.append(x) def composed_fun(task): for x in funs_lst: ret = x(task) if ret: return ret return None return composed_fun, dvars if shell: return compile_fun_shell(line) else: return compile_fun_noshell(line) def task_factory(name, func=None, vars=None, color='GREEN', ext_in=[], ext_out=[], before=[], after=[], shell=False, scan=None): """ Returns a new task subclass with the function ``run`` compiled from the line given. :param func: method run :type func: string or function :param vars: list of variables to hash :type vars: list of string :param color: color to use :type color: string :param shell: when *func* is a string, enable/disable the use of the shell :type shell: bool :param scan: method scan :type scan: function :rtype: :py:class:`waflib.Task.Task` """ params = { 'vars': vars or [], # function arguments are static, and this one may be modified by the class 'color': color, 'name': name, 'ext_in': Utils.to_list(ext_in), 'ext_out': Utils.to_list(ext_out), 'before': Utils.to_list(before), 'after': Utils.to_list(after), 'shell': shell, 'scan': scan, } if isinstance(func, str) or isinstance(func, tuple): params['run_str'] = func else: params['run'] = func cls = type(Task)(name, (Task,), params) global classes classes[name] = cls return cls def always_run(cls): """ Task class decorator Set all task instances of this class to be executed whenever a build is started The task signature is calculated, but the result of the comparation between task signatures is bypassed """ old = cls.runnable_status def always(self): ret = old(self) if ret == SKIP_ME: ret = RUN_ME return ret cls.runnable_status = always return cls def update_outputs(cls): """ Task class decorator If you want to create files in the source directory. For example, to keep *foo.txt* in the source directory, create it first and declare:: def build(bld): bld(rule='cp ${SRC} ${TGT}', source='wscript', target='foo.txt', update_outputs=True) """ old_post_run = cls.post_run def post_run(self): old_post_run(self) for node in self.outputs: node.sig = node.cache_sig = Utils.h_file(node.abspath()) self.generator.bld.task_sigs[node.abspath()] = self.uid() # issue #1017 cls.post_run = post_run old_runnable_status = cls.runnable_status def runnable_status(self): status = old_runnable_status(self) if status != RUN_ME: return status try: # by default, we check that the output nodes have the signature of the task # perform a second check, returning 'SKIP_ME' as we are expecting that # the signatures do not match bld = self.generator.bld prev_sig = bld.task_sigs[self.uid()] if prev_sig == self.signature(): for x in self.outputs: if not x.is_child_of(bld.bldnode): # special case of files created in the source directory # hash them here for convenience -_- x.sig = Utils.h_file(x.abspath()) if not x.sig or bld.task_sigs[x.abspath()] != self.uid(): return RUN_ME return SKIP_ME except OSError: pass except IOError: pass except KeyError: pass except IndexError: pass except AttributeError: pass return RUN_ME cls.runnable_status = runnable_status return cls 1.9.12~dfsg/waflib/ConfigSet.py0000644000000000000000000001750713214314510015051 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ ConfigSet: a special dict The values put in :py:class:`ConfigSet` must be lists """ import copy, re, os from waflib import Logs, Utils re_imp = re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$', re.M) class ConfigSet(object): """ A dict that honor serialization and parent relationships. The serialization format is human-readable (python-like) and performed by using eval() and repr(). For high performance prefer pickle. Do not store functions as they are not serializable. The values can be accessed by attributes or by keys:: from waflib.ConfigSet import ConfigSet env = ConfigSet() env.FOO = 'test' env['FOO'] = 'test' """ __slots__ = ('table', 'parent') def __init__(self, filename=None): self.table = {} """ Internal dict holding the object values """ #self.parent = None if filename: self.load(filename) def __contains__(self, key): """ Enable the *in* syntax:: if 'foo' in env: print(env['foo']) """ if key in self.table: return True try: return self.parent.__contains__(key) except AttributeError: return False # parent may not exist def keys(self): """Dict interface (unknown purpose)""" keys = set() cur = self while cur: keys.update(cur.table.keys()) cur = getattr(cur, 'parent', None) keys = list(keys) keys.sort() return keys def __str__(self): """Text representation of the ConfigSet (for debugging purposes)""" return "\n".join(["%r %r" % (x, self.__getitem__(x)) for x in self.keys()]) def __getitem__(self, key): """ Dictionary interface: get value from key:: def configure(conf): conf.env['foo'] = {} print(env['foo']) """ try: while 1: x = self.table.get(key, None) if not x is None: return x self = self.parent except AttributeError: return [] def __setitem__(self, key, value): """ Dictionary interface: get value from key """ self.table[key] = value def __delitem__(self, key): """ Dictionary interface: get value from key """ self[key] = [] def __getattr__(self, name): """ Attribute access provided for convenience. The following forms are equivalent:: def configure(conf): conf.env.value conf.env['value'] """ if name in self.__slots__: return object.__getattr__(self, name) else: return self[name] def __setattr__(self, name, value): """ Attribute access provided for convenience. The following forms are equivalent:: def configure(conf): conf.env.value = x env['value'] = x """ if name in self.__slots__: object.__setattr__(self, name, value) else: self[name] = value def __delattr__(self, name): """ Attribute access provided for convenience. The following forms are equivalent:: def configure(conf): del env.value del env['value'] """ if name in self.__slots__: object.__delattr__(self, name) else: del self[name] def derive(self): """ Returns a new ConfigSet deriving from self. The copy returned will be a shallow copy:: from waflib.ConfigSet import ConfigSet env = ConfigSet() env.append_value('CFLAGS', ['-O2']) child = env.derive() child.CFLAGS.append('test') # warning! this will modify 'env' child.CFLAGS = ['-O3'] # new list, ok child.append_value('CFLAGS', ['-O3']) # ok Use :py:func:`ConfigSet.detach` to detach the child from the parent. """ newenv = ConfigSet() newenv.parent = self return newenv def detach(self): """ Detach self from its parent (if existing) Modifying the parent :py:class:`ConfigSet` will not change the current object Modifying this :py:class:`ConfigSet` will not modify the parent one. """ tbl = self.get_merged_dict() try: delattr(self, 'parent') except AttributeError: pass else: keys = tbl.keys() for x in keys: tbl[x] = copy.deepcopy(tbl[x]) self.table = tbl return self def get_flat(self, key): """ Return a value as a string. If the input is a list, the value returned is space-separated. :param key: key to use :type key: string """ s = self[key] if isinstance(s, str): return s return ' '.join(s) def _get_list_value_for_modification(self, key): """ Return a list value for further modification. The list may be modified inplace and there is no need to do this afterwards:: self.table[var] = value """ try: value = self.table[key] except KeyError: try: value = self.parent[key] except AttributeError: value = [] if isinstance(value, list): value = value[:] else: value = [value] else: if not isinstance(value, list): value = [value] self.table[key] = value return value def append_value(self, var, val): """ Appends a value to the specified config key:: def build(bld): bld.env.append_value('CFLAGS', ['-O2']) The value must be a list or a tuple """ if isinstance(val, str): # if there were string everywhere we could optimize this val = [val] current_value = self._get_list_value_for_modification(var) current_value.extend(val) def prepend_value(self, var, val): """ Prepends a value to the specified item:: def configure(conf): conf.env.prepend_value('CFLAGS', ['-O2']) The value must be a list or a tuple """ if isinstance(val, str): val = [val] self.table[var] = val + self._get_list_value_for_modification(var) def append_unique(self, var, val): """ Append a value to the specified item only if it's not already present:: def build(bld): bld.env.append_unique('CFLAGS', ['-O2', '-g']) The value must be a list or a tuple """ if isinstance(val, str): val = [val] current_value = self._get_list_value_for_modification(var) for x in val: if x not in current_value: current_value.append(x) def get_merged_dict(self): """ Compute the merged dictionary from the fusion of self and all its parent :rtype: a ConfigSet object """ table_list = [] env = self while 1: table_list.insert(0, env.table) try: env = env.parent except AttributeError: break merged_table = {} for table in table_list: merged_table.update(table) return merged_table def store(self, filename): """ Write the :py:class:`ConfigSet` data into a file. See :py:meth:`ConfigSet.load` for reading such files. :param filename: file to use :type filename: string """ try: os.makedirs(os.path.split(filename)[0]) except OSError: pass buf = [] merged_table = self.get_merged_dict() keys = list(merged_table.keys()) keys.sort() try: fun = ascii except NameError: fun = repr for k in keys: if k != 'undo_stack': buf.append('%s = %s\n' % (k, fun(merged_table[k]))) Utils.writef(filename, ''.join(buf)) def load(self, filename): """ Retrieve the :py:class:`ConfigSet` data from a file. See :py:meth:`ConfigSet.store` for writing such files :param filename: file to use :type filename: string """ tbl = self.table code = Utils.readf(filename, m='rU') for m in re_imp.finditer(code): g = m.group tbl[g(2)] = eval(g(3)) Logs.debug('env: %s' % str(self.table)) def update(self, d): """ Dictionary interface: replace values from another dict :param d: object to use the value from :type d: dict-like object """ for k, v in d.items(): self[k] = v def stash(self): """ Store the object state, to provide a kind of transaction support:: env = ConfigSet() env.stash() try: env.append_value('CFLAGS', '-O3') call_some_method(env) finally: env.revert() The history is kept in a stack, and is lost during the serialization by :py:meth:`ConfigSet.store` """ orig = self.table tbl = self.table = self.table.copy() for x in tbl.keys(): tbl[x] = copy.deepcopy(tbl[x]) self.undo_stack = self.undo_stack + [orig] def revert(self): """ Reverts the object to a previous state. See :py:meth:`ConfigSet.stash` """ self.table = self.undo_stack.pop(-1) 1.9.12~dfsg/waflib/Context.py0000644000000000000000000004612513214314510014612 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010 (ita) """ Classes and functions required for waf commands """ import os, re, imp, sys from waflib import Utils, Errors, Logs import waflib.Node # the following 3 constants are updated on each new release (do not touch) HEXVERSION=0x1081100 """Constant updated on new releases""" WAFVERSION="1.8.17" """Constant updated on new releases""" WAFREVISION="cd7579a727d1b390bf9cbf111c1b20e811370bc0" """Git revision when the waf version is updated""" ABI = 98 """Version of the build data cache file format (used in :py:const:`waflib.Context.DBFILE`)""" DBFILE = '.wafpickle-%s-%d-%d' % (sys.platform, sys.hexversion, ABI) """Name of the pickle file for storing the build data""" APPNAME = 'APPNAME' """Default application name (used by ``waf dist``)""" VERSION = 'VERSION' """Default application version (used by ``waf dist``)""" TOP = 'top' """The variable name for the top-level directory in wscript files""" OUT = 'out' """The variable name for the output directory in wscript files""" WSCRIPT_FILE = 'wscript' """Name of the waf script files""" launch_dir = '' """Directory from which waf has been called""" run_dir = '' """Location of the wscript file to use as the entry point""" top_dir = '' """Location of the project directory (top), if the project was configured""" out_dir = '' """Location of the build directory (out), if the project was configured""" waf_dir = '' """Directory containing the waf modules""" local_repo = '' """Local repository containing additional Waf tools (plugins)""" remote_repo = 'https://raw.githubusercontent.com/waf-project/waf/master/' """ Remote directory containing downloadable waf tools. The missing tools can be downloaded by using:: $ waf configure --download """ remote_locs = ['waflib/extras', 'waflib/Tools'] """ Remote directories for use with :py:const:`waflib.Context.remote_repo` """ g_module = None """ Module representing the main wscript file (see :py:const:`waflib.Context.run_dir`) """ STDOUT = 1 STDERR = -1 BOTH = 0 classes = [] """ List of :py:class:`waflib.Context.Context` subclasses that can be used as waf commands. The classes are added automatically by a metaclass. """ def create_context(cmd_name, *k, **kw): """ Create a new :py:class:`waflib.Context.Context` instance corresponding to the given command. Used in particular by :py:func:`waflib.Scripting.run_command` :param cmd_name: command :type cmd_name: string :param k: arguments to give to the context class initializer :type k: list :param k: keyword arguments to give to the context class initializer :type k: dict """ global classes for x in classes: if x.cmd == cmd_name: return x(*k, **kw) ctx = Context(*k, **kw) ctx.fun = cmd_name return ctx class store_context(type): """ Metaclass for storing the command classes into the list :py:const:`waflib.Context.classes` Context classes must provide an attribute 'cmd' representing the command to execute """ def __init__(cls, name, bases, dict): super(store_context, cls).__init__(name, bases, dict) name = cls.__name__ if name == 'ctx' or name == 'Context': return try: cls.cmd except AttributeError: raise Errors.WafError('Missing command for the context class %r (cmd)' % name) if not getattr(cls, 'fun', None): cls.fun = cls.cmd global classes classes.insert(0, cls) ctx = store_context('ctx', (object,), {}) """Base class for the :py:class:`waflib.Context.Context` classes""" class Context(ctx): """ Default context for waf commands, and base class for new command contexts. Context objects are passed to top-level functions:: def foo(ctx): print(ctx.__class__.__name__) # waflib.Context.Context Subclasses must define the attribute 'cmd': :param cmd: command to execute as in ``waf cmd`` :type cmd: string :param fun: function name to execute when the command is called :type fun: string .. inheritance-diagram:: waflib.Context.Context waflib.Build.BuildContext waflib.Build.InstallContext waflib.Build.UninstallContext waflib.Build.StepContext waflib.Build.ListContext waflib.Configure.ConfigurationContext waflib.Scripting.Dist waflib.Scripting.DistCheck waflib.Build.CleanContext """ errors = Errors """ Shortcut to :py:mod:`waflib.Errors` provided for convenience """ tools = {} """ A cache for modules (wscript files) read by :py:meth:`Context.Context.load` """ def __init__(self, **kw): try: rd = kw['run_dir'] except KeyError: global run_dir rd = run_dir # binds the context to the nodes in use to avoid a context singleton self.node_class = type("Nod3", (waflib.Node.Node,), {}) self.node_class.__module__ = "waflib.Node" self.node_class.ctx = self self.root = self.node_class('', None) self.cur_script = None self.path = self.root.find_dir(rd) self.stack_path = [] self.exec_dict = {'ctx':self, 'conf':self, 'bld':self, 'opt':self} self.logger = None def __hash__(self): """ Return a hash value for storing context objects in dicts or sets. The value is not persistent. :return: hash value :rtype: int """ return id(self) def finalize(self): """ Use to free resources such as open files potentially held by the logger """ try: logger = self.logger except AttributeError: pass else: Logs.free_logger(logger) delattr(self, 'logger') def load(self, tool_list, *k, **kw): """ Load a Waf tool as a module, and try calling the function named :py:const:`waflib.Context.Context.fun` from it. A ``tooldir`` value may be provided as a list of module paths. :type tool_list: list of string or space-separated string :param tool_list: list of Waf tools to use """ tools = Utils.to_list(tool_list) path = Utils.to_list(kw.get('tooldir', '')) with_sys_path = kw.get('with_sys_path', True) for t in tools: module = load_tool(t, path, with_sys_path=with_sys_path) fun = getattr(module, kw.get('name', self.fun), None) if fun: fun(self) def execute(self): """ Execute the command. Redefine this method in subclasses. """ global g_module self.recurse([os.path.dirname(g_module.root_path)]) def pre_recurse(self, node): """ Method executed immediately before a folder is read by :py:meth:`waflib.Context.Context.recurse`. The node given is set as an attribute ``self.cur_script``, and as the current path ``self.path`` :param node: script :type node: :py:class:`waflib.Node.Node` """ self.stack_path.append(self.cur_script) self.cur_script = node self.path = node.parent def post_recurse(self, node): """ Restore ``self.cur_script`` and ``self.path`` right after :py:meth:`waflib.Context.Context.recurse` terminates. :param node: script :type node: :py:class:`waflib.Node.Node` """ self.cur_script = self.stack_path.pop() if self.cur_script: self.path = self.cur_script.parent def recurse(self, dirs, name=None, mandatory=True, once=True, encoding=None): """ Run user code from the supplied list of directories. The directories can be either absolute, or relative to the directory of the wscript file. The methods :py:meth:`waflib.Context.Context.pre_recurse` and :py:meth:`waflib.Context.Context.post_recurse` are called immediately before and after a script has been executed. :param dirs: List of directories to visit :type dirs: list of string or space-separated string :param name: Name of function to invoke from the wscript :type name: string :param mandatory: whether sub wscript files are required to exist :type mandatory: bool :param once: read the script file once for a particular context :type once: bool """ try: cache = self.recurse_cache except AttributeError: cache = self.recurse_cache = {} for d in Utils.to_list(dirs): if not os.path.isabs(d): # absolute paths only d = os.path.join(self.path.abspath(), d) WSCRIPT = os.path.join(d, WSCRIPT_FILE) WSCRIPT_FUN = WSCRIPT + '_' + (name or self.fun) node = self.root.find_node(WSCRIPT_FUN) if node and (not once or node not in cache): cache[node] = True self.pre_recurse(node) try: function_code = node.read('rU', encoding) exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict) finally: self.post_recurse(node) elif not node: node = self.root.find_node(WSCRIPT) tup = (node, name or self.fun) if node and (not once or tup not in cache): cache[tup] = True self.pre_recurse(node) try: wscript_module = load_module(node.abspath(), encoding=encoding) user_function = getattr(wscript_module, (name or self.fun), None) if not user_function: if not mandatory: continue raise Errors.WafError('No function %s defined in %s' % (name or self.fun, node.abspath())) user_function(self) finally: self.post_recurse(node) elif not node: if not mandatory: continue try: os.listdir(d) except OSError: raise Errors.WafError('Cannot read the folder %r' % d) raise Errors.WafError('No wscript file in directory %s' % d) def exec_command(self, cmd, **kw): """ Execute a command and return the exit status. If the context has the attribute 'log', capture and log the process stderr/stdout for logging purposes:: def run(tsk): ret = tsk.generator.bld.exec_command('touch foo.txt') return ret This method captures the standard/error outputs (Issue 1101), but it does not return the values unlike :py:meth:`waflib.Context.Context.cmd_and_log` :param cmd: command argument for subprocess.Popen :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. """ subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) Logs.debug('runner: %r' % (cmd,)) Logs.debug('runner_env: kw=%s' % kw) if self.logger: self.logger.info(cmd) if 'stdout' not in kw: kw['stdout'] = subprocess.PIPE if 'stderr' not in kw: kw['stderr'] = subprocess.PIPE if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): raise Errors.WafError("Program %s not found!" % cmd[0]) wargs = {} if 'timeout' in kw: if kw['timeout'] is not None: wargs['timeout'] = kw['timeout'] del kw['timeout'] if 'input' in kw: if kw['input']: wargs['input'] = kw['input'] kw['stdin'] = Utils.subprocess.PIPE del kw['input'] try: if kw['stdout'] or kw['stderr']: p = subprocess.Popen(cmd, **kw) (out, err) = p.communicate(**wargs) ret = p.returncode else: out, err = (None, None) ret = subprocess.Popen(cmd, **kw).wait(**wargs) except Exception as e: raise Errors.WafError('Execution failure: %s' % str(e), ex=e) if out: if not isinstance(out, str): out = out.decode(sys.stdout.encoding or 'iso8859-1') if self.logger: self.logger.debug('out: %s' % out) else: Logs.info(out, extra={'stream':sys.stdout, 'c1': ''}) if err: if not isinstance(err, str): err = err.decode(sys.stdout.encoding or 'iso8859-1') if self.logger: self.logger.error('err: %s' % err) else: Logs.info(err, extra={'stream':sys.stderr, 'c1': ''}) return ret def cmd_and_log(self, cmd, **kw): """ Execute a command and return stdout/stderr if the execution is successful. An exception is thrown when the exit status is non-0. In that case, both stderr and stdout will be bound to the WafError object:: def configure(conf): out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH) (out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH) (out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT) try: conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH) except Exception as e: print(e.stdout, e.stderr) :param cmd: args for subprocess.Popen :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. """ subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) Logs.debug('runner: %r' % (cmd,)) if 'quiet' in kw: quiet = kw['quiet'] del kw['quiet'] else: quiet = None if 'output' in kw: to_ret = kw['output'] del kw['output'] else: to_ret = STDOUT if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): raise Errors.WafError("Program %s not found!" % cmd[0]) kw['stdout'] = kw['stderr'] = subprocess.PIPE if quiet is None: self.to_log(cmd) wargs = {} if 'timeout' in kw: if kw['timeout'] is not None: wargs['timeout'] = kw['timeout'] del kw['timeout'] if 'input' in kw: if kw['input']: wargs['input'] = kw['input'] kw['stdin'] = Utils.subprocess.PIPE del kw['input'] try: p = subprocess.Popen(cmd, **kw) (out, err) = p.communicate(**wargs) except Exception as e: raise Errors.WafError('Execution failure: %s' % str(e), ex=e) if not isinstance(out, str): out = out.decode(sys.stdout.encoding or 'iso8859-1') if not isinstance(err, str): err = err.decode(sys.stdout.encoding or 'iso8859-1') if out and quiet != STDOUT and quiet != BOTH: self.to_log('out: %s' % out) if err and quiet != STDERR and quiet != BOTH: self.to_log('err: %s' % err) if p.returncode: e = Errors.WafError('Command %r returned %r' % (cmd, p.returncode)) e.returncode = p.returncode e.stderr = err e.stdout = out raise e if to_ret == BOTH: return (out, err) elif to_ret == STDERR: return err return out def fatal(self, msg, ex=None): """ Raise a configuration error to interrupt the execution immediately:: def configure(conf): conf.fatal('a requirement is missing') :param msg: message to display :type msg: string :param ex: optional exception object :type ex: exception """ if self.logger: self.logger.info('from %s: %s' % (self.path.abspath(), msg)) try: msg = '%s\n(complete log in %s)' % (msg, self.logger.handlers[0].baseFilename) except Exception: pass raise self.errors.ConfigurationError(msg, ex=ex) def to_log(self, msg): """ Log some information to the logger (if present), or to stderr. If the message is empty, it is not printed:: def build(bld): bld.to_log('starting the build') When in doubt, override this method, or provide a logger on the context class. :param msg: message :type msg: string """ if not msg: return if self.logger: self.logger.info(msg) else: sys.stderr.write(str(msg)) sys.stderr.flush() def msg(self, *k, **kw): """ Print a configuration message of the form ``msg: result``. The second part of the message will be in colors. The output can be disabled easly by setting ``in_msg`` to a positive value:: def configure(conf): self.in_msg = 1 conf.msg('Checking for library foo', 'ok') # no output :param msg: message to display to the user :type msg: string :param result: result to display :type result: string or boolean :param color: color to use, see :py:const:`waflib.Logs.colors_lst` :type color: string """ try: msg = kw['msg'] except KeyError: msg = k[0] self.start_msg(msg, **kw) try: result = kw['result'] except KeyError: result = k[1] color = kw.get('color', None) if not isinstance(color, str): color = result and 'GREEN' or 'YELLOW' self.end_msg(result, color, **kw) def start_msg(self, *k, **kw): """ Print the beginning of a 'Checking for xxx' message. See :py:meth:`waflib.Context.Context.msg` """ if kw.get('quiet', None): return msg = kw.get('msg', None) or k[0] try: if self.in_msg: self.in_msg += 1 return except AttributeError: self.in_msg = 0 self.in_msg += 1 try: self.line_just = max(self.line_just, len(msg)) except AttributeError: self.line_just = max(40, len(msg)) for x in (self.line_just * '-', msg): self.to_log(x) Logs.pprint('NORMAL', "%s :" % msg.ljust(self.line_just), sep='') def end_msg(self, *k, **kw): """Print the end of a 'Checking for' message. See :py:meth:`waflib.Context.Context.msg`""" if kw.get('quiet', None): return self.in_msg -= 1 if self.in_msg: return result = kw.get('result', None) or k[0] defcolor = 'GREEN' if result == True: msg = 'ok' elif result == False: msg = 'not found' defcolor = 'YELLOW' else: msg = str(result) self.to_log(msg) try: color = kw['color'] except KeyError: if len(k) > 1 and k[1] in Logs.colors_lst: # compatibility waf 1.7 color = k[1] else: color = defcolor Logs.pprint(color, msg) def load_special_tools(self, var, ban=[]): global waf_dir if os.path.isdir(waf_dir): lst = self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var) for x in lst: if not x.name in ban: load_tool(x.name.replace('.py', '')) else: from zipfile import PyZipFile waflibs = PyZipFile(waf_dir) lst = waflibs.namelist() for x in lst: if not re.match("waflib/extras/%s" % var.replace("*", ".*"), var): continue f = os.path.basename(x) doban = False for b in ban: r = b.replace("*", ".*") if re.match(r, f): doban = True if not doban: f = f.replace('.py', '') load_tool(f) cache_modules = {} """ Dictionary holding already loaded modules, keyed by their absolute path. The modules are added automatically by :py:func:`waflib.Context.load_module` """ def load_module(path, encoding=None): """ Load a source file as a python module. :param path: file path :type path: string :return: Loaded Python module :rtype: module """ try: return cache_modules[path] except KeyError: pass module = imp.new_module(WSCRIPT_FILE) try: code = Utils.readf(path, m='rU', encoding=encoding) except EnvironmentError: raise Errors.WafError('Could not read the file %r' % path) module_dir = os.path.dirname(path) sys.path.insert(0, module_dir) try : exec(compile(code, path, 'exec'), module.__dict__) finally: sys.path.remove(module_dir) cache_modules[path] = module return module def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): """ Import a Waf tool (python module), and store it in the dict :py:const:`waflib.Context.Context.tools` :type tool: string :param tool: Name of the tool :type tooldir: list :param tooldir: List of directories to search for the tool module :type with_sys_path: boolean :param with_sys_path: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs """ if tool == 'java': tool = 'javaw' # jython else: tool = tool.replace('++', 'xx') origSysPath = sys.path if not with_sys_path: sys.path = [] try: if tooldir: assert isinstance(tooldir, list) sys.path = tooldir + sys.path try: __import__(tool) finally: for d in tooldir: sys.path.remove(d) ret = sys.modules[tool] Context.tools[tool] = ret return ret else: if not with_sys_path: sys.path.insert(0, waf_dir) try: for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): try: __import__(x % tool) break except ImportError: x = None if x is None: # raise an exception __import__(tool) finally: if not with_sys_path: sys.path.remove(waf_dir) ret = sys.modules[x % tool] Context.tools[tool] = ret return ret finally: if not with_sys_path: sys.path += origSysPath 1.9.12~dfsg/waflib/__init__.py0000644000000000000000000000010713214314510014713 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) 1.9.12~dfsg/waflib/TaskGen.py0000644000000000000000000006004713214314510014521 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ Task generators The class :py:class:`waflib.TaskGen.task_gen` encapsulates the creation of task objects (low-level code) The instances can have various parameters, but the creation of task nodes (Task.py) is always postponed. To achieve this, various methods are called from the method "apply" """ import copy, re, os from waflib import Task, Utils, Logs, Errors, ConfigSet, Node feats = Utils.defaultdict(set) """remember the methods declaring features""" HEADER_EXTS = ['.h', '.hpp', '.hxx', '.hh'] class task_gen(object): """ Instances of this class create :py:class:`waflib.Task.TaskBase` when calling the method :py:meth:`waflib.TaskGen.task_gen.post` from the main thread. A few notes: * The methods to call (*self.meths*) can be specified dynamically (removing, adding, ..) * The 'features' are used to add methods to self.meths and then execute them * The attribute 'path' is a node representing the location of the task generator * The tasks created are added to the attribute *tasks* * The attribute 'idx' is a counter of task generators in the same path """ mappings = Utils.ordered_iter_dict() """Mappings are global file extension mappings, they are retrieved in the order of definition""" prec = Utils.defaultdict(list) """Dict holding the precedence rules for task generator methods""" def __init__(self, *k, **kw): """ The task generator objects predefine various attributes (source, target) for possible processing by process_rule (make-like rules) or process_source (extensions, misc methods) The tasks are stored on the attribute 'tasks'. They are created by calling methods listed in self.meths *or* referenced in the attribute features A topological sort is performed to ease the method re-use. The extra key/value elements passed in kw are set as attributes """ # so we will have to play with directed acyclic graphs # detect cycles, etc self.source = '' self.target = '' self.meths = [] """ List of method names to execute (it is usually a good idea to avoid touching this) """ self.prec = Utils.defaultdict(list) """ Precedence table for sorting the methods in self.meths """ self.mappings = {} """ List of mappings {extension -> function} for processing files by extension This is very rarely used, so we do not use an ordered dict here """ self.features = [] """ List of feature names for bringing new methods in """ self.tasks = [] """ List of tasks created. """ if not 'bld' in kw: # task generators without a build context :-/ self.env = ConfigSet.ConfigSet() self.idx = 0 self.path = None else: self.bld = kw['bld'] self.env = self.bld.env.derive() self.path = self.bld.path # emulate chdir when reading scripts # provide a unique id try: self.idx = self.bld.idx[id(self.path)] = self.bld.idx.get(id(self.path), 0) + 1 except AttributeError: self.bld.idx = {} self.idx = self.bld.idx[id(self.path)] = 1 for key, val in kw.items(): setattr(self, key, val) def __str__(self): """for debugging purposes""" return "" % (self.name, self.path.abspath()) def __repr__(self): """for debugging purposes""" lst = [] for x in self.__dict__.keys(): if x not in ('env', 'bld', 'compiled_tasks', 'tasks'): lst.append("%s=%s" % (x, repr(getattr(self, x)))) return "bld(%s) in %s" % (", ".join(lst), self.path.abspath()) def get_name(self): """ If not set, the name is computed from the target name:: def build(bld): x = bld(name='foo') x.get_name() # foo y = bld(target='bar') y.get_name() # bar :rtype: string :return: name of this task generator """ try: return self._name except AttributeError: if isinstance(self.target, list): lst = [str(x) for x in self.target] name = self._name = ','.join(lst) else: name = self._name = str(self.target) return name def set_name(self, name): self._name = name name = property(get_name, set_name) def to_list(self, val): """ Ensure that a parameter is a list :type val: string or list of string :param val: input to return as a list :rtype: list """ if isinstance(val, str): return val.split() else: return val def post(self): """ Create task objects. The following operations are performed: #. The body of this method is called only once and sets the attribute ``posted`` #. The attribute ``features`` is used to add more methods in ``self.meths`` #. The methods are sorted by the precedence table ``self.prec`` or `:waflib:attr:waflib.TaskGen.task_gen.prec` #. The methods are then executed in order #. The tasks created are added to :py:attr:`waflib.TaskGen.task_gen.tasks` """ # we could add a decorator to let the task run once, but then python 2.3 will be difficult to support if getattr(self, 'posted', None): #error("OBJECT ALREADY POSTED" + str( self)) return False self.posted = True keys = set(self.meths) # add the methods listed in the features self.features = Utils.to_list(self.features) for x in self.features + ['*']: st = feats[x] if not st: if not x in Task.classes: Logs.warn('feature %r does not exist - bind at least one method to it' % x) keys.update(list(st)) # ironpython 2.7 wants the cast to list # copy the precedence table prec = {} prec_tbl = self.prec or task_gen.prec for x in prec_tbl: if x in keys: prec[x] = prec_tbl[x] # elements disconnected tmp = [] for a in keys: for x in prec.values(): if a in x: break else: tmp.append(a) tmp.sort() # topological sort out = [] while tmp: e = tmp.pop() if e in keys: out.append(e) try: nlst = prec[e] except KeyError: pass else: del prec[e] for x in nlst: for y in prec: if x in prec[y]: break else: tmp.append(x) if prec: raise Errors.WafError('Cycle detected in the method execution %r' % prec) out.reverse() self.meths = out # then we run the methods in order Logs.debug('task_gen: posting %s %d' % (self, id(self))) for x in out: try: v = getattr(self, x) except AttributeError: raise Errors.WafError('%r is not a valid task generator method' % x) Logs.debug('task_gen: -> %s (%d)' % (x, id(self))) v() Logs.debug('task_gen: posted %s' % self.name) return True def get_hook(self, node): """ :param node: Input file to process :type node: :py:class:`waflib.Tools.Node.Node` :return: A method able to process the input node by looking at the extension :rtype: function """ name = node.name if self.mappings: for k in self.mappings: if name.endswith(k): return self.mappings[k] for k in task_gen.mappings: if name.endswith(k): return task_gen.mappings[k] raise Errors.WafError("File %r has no mapping in %r (have you forgotten to load a waf tool?)" % (node, task_gen.mappings.keys())) def create_task(self, name, src=None, tgt=None, **kw): """ Wrapper for creating task instances. The classes are retrieved from the context class if possible, then from the global dict Task.classes. :param name: task class name :type name: string :param src: input nodes :type src: list of :py:class:`waflib.Tools.Node.Node` :param tgt: output nodes :type tgt: list of :py:class:`waflib.Tools.Node.Node` :return: A task object :rtype: :py:class:`waflib.Task.TaskBase` """ task = Task.classes[name](env=self.env.derive(), generator=self) if src: task.set_inputs(src) if tgt: task.set_outputs(tgt) task.__dict__.update(kw) self.tasks.append(task) return task def clone(self, env): """ Make a copy of a task generator. Once the copy is made, it is necessary to ensure that the it does not create the same output files as the original, or the same files may be compiled several times. :param env: A configuration set :type env: :py:class:`waflib.ConfigSet.ConfigSet` :return: A copy :rtype: :py:class:`waflib.TaskGen.task_gen` """ newobj = self.bld() for x in self.__dict__: if x in ('env', 'bld'): continue elif x in ('path', 'features'): setattr(newobj, x, getattr(self, x)) else: setattr(newobj, x, copy.copy(getattr(self, x))) newobj.posted = False if isinstance(env, str): newobj.env = self.bld.all_envs[env].derive() else: newobj.env = env.derive() return newobj def declare_chain(name='', rule=None, reentrant=None, color='BLUE', ext_in=[], ext_out=[], before=[], after=[], decider=None, scan=None, install_path=None, shell=False): """ Create a new mapping and a task class for processing files by extension. See Tools/flex.py for an example. :param name: name for the task class :type name: string :param rule: function to execute or string to be compiled in a function :type rule: string or function :param reentrant: re-inject the output file in the process (done automatically, set to 0 to disable) :type reentrant: int :param color: color for the task output :type color: string :param ext_in: execute the task only after the files of such extensions are created :type ext_in: list of string :param ext_out: execute the task only before files of such extensions are processed :type ext_out: list of string :param before: execute instances of this task before classes of the given names :type before: list of string :param after: execute instances of this task after classes of the given names :type after: list of string :param decider: if present, use it to create the output nodes for the task :type decider: function :param scan: scanner function for the task :type scan: function :param install_path: installation path for the output nodes :type install_path: string """ ext_in = Utils.to_list(ext_in) ext_out = Utils.to_list(ext_out) if not name: name = rule cls = Task.task_factory(name, rule, color=color, ext_in=ext_in, ext_out=ext_out, before=before, after=after, scan=scan, shell=shell) def x_file(self, node): ext = decider and decider(self, node) or cls.ext_out if ext_in: _ext_in = ext_in[0] tsk = self.create_task(name, node) cnt = 0 keys = set(self.mappings.keys()) | set(self.__class__.mappings.keys()) for x in ext: k = node.change_ext(x, ext_in=_ext_in) tsk.outputs.append(k) if reentrant != None: if cnt < int(reentrant): self.source.append(k) else: # reinject downstream files into the build for y in keys: # ~ nfile * nextensions :-/ if k.name.endswith(y): self.source.append(k) break cnt += 1 if install_path: self.bld.install_files(install_path, tsk.outputs) return tsk for x in cls.ext_in: task_gen.mappings[x] = x_file return x_file def taskgen_method(func): """ Decorator: register a method as a task generator method. The function must accept a task generator as first parameter:: from waflib.TaskGen import taskgen_method @taskgen_method def mymethod(self): pass :param func: task generator method to add :type func: function :rtype: function """ setattr(task_gen, func.__name__, func) return func def feature(*k): """ Decorator: register a task generator method that will be executed when the object attribute 'feature' contains the corresponding key(s):: from waflib.Task import feature @feature('myfeature') def myfunction(self): print('that is my feature!') def build(bld): bld(features='myfeature') :param k: feature names :type k: list of string """ def deco(func): setattr(task_gen, func.__name__, func) for name in k: feats[name].update([func.__name__]) return func return deco def before_method(*k): """ Decorator: register a task generator method which will be executed before the functions of given name(s):: from waflib.TaskGen import feature, before @feature('myfeature') @before_method('fun2') def fun1(self): print('feature 1!') @feature('myfeature') def fun2(self): print('feature 2!') def build(bld): bld(features='myfeature') :param k: method names :type k: list of string """ def deco(func): setattr(task_gen, func.__name__, func) for fun_name in k: if not func.__name__ in task_gen.prec[fun_name]: task_gen.prec[fun_name].append(func.__name__) #task_gen.prec[fun_name].sort() return func return deco before = before_method def after_method(*k): """ Decorator: register a task generator method which will be executed after the functions of given name(s):: from waflib.TaskGen import feature, after @feature('myfeature') @after_method('fun2') def fun1(self): print('feature 1!') @feature('myfeature') def fun2(self): print('feature 2!') def build(bld): bld(features='myfeature') :param k: method names :type k: list of string """ def deco(func): setattr(task_gen, func.__name__, func) for fun_name in k: if not fun_name in task_gen.prec[func.__name__]: task_gen.prec[func.__name__].append(fun_name) #task_gen.prec[func.__name__].sort() return func return deco after = after_method def extension(*k): """ Decorator: register a task generator method which will be invoked during the processing of source files for the extension given:: from waflib import Task class mytask(Task): run_str = 'cp ${SRC} ${TGT}' @extension('.moo') def create_maa_file(self, node): self.create_task('mytask', node, node.change_ext('.maa')) def build(bld): bld(source='foo.moo') """ def deco(func): setattr(task_gen, func.__name__, func) for x in k: task_gen.mappings[x] = func return func return deco # --------------------------------------------------------------- # The following methods are task generator methods commonly used # they are almost examples, the rest of waf core does not depend on them @taskgen_method def to_nodes(self, lst, path=None): """ Convert the input list into a list of nodes. It is used by :py:func:`waflib.TaskGen.process_source` and :py:func:`waflib.TaskGen.process_rule`. It is designed for source files, for folders, see :py:func:`waflib.Tools.ccroot.to_incnodes`: :param lst: input list :type lst: list of string and nodes :param path: path from which to search the nodes (by default, :py:attr:`waflib.TaskGen.task_gen.path`) :type path: :py:class:`waflib.Tools.Node.Node` :rtype: list of :py:class:`waflib.Tools.Node.Node` """ tmp = [] path = path or self.path find = path.find_resource if isinstance(lst, Node.Node): lst = [lst] # either a list or a string, convert to a list of nodes for x in Utils.to_list(lst): if isinstance(x, str): node = find(x) else: node = x if not node: raise Errors.WafError("source not found: %r in %r" % (x, self)) tmp.append(node) return tmp @feature('*') def process_source(self): """ Process each element in the attribute ``source`` by extension. #. The *source* list is converted through :py:meth:`waflib.TaskGen.to_nodes` to a list of :py:class:`waflib.Node.Node` first. #. File extensions are mapped to methods having the signature: ``def meth(self, node)`` by :py:meth:`waflib.TaskGen.extension` #. The method is retrieved through :py:meth:`waflib.TaskGen.task_gen.get_hook` #. When called, the methods may modify self.source to append more source to process #. The mappings can map an extension or a filename (see the code below) """ self.source = self.to_nodes(getattr(self, 'source', [])) for node in self.source: self.get_hook(node)(self, node) @feature('*') @before_method('process_source') def process_rule(self): """ Process the attribute ``rule``. When present, :py:meth:`waflib.TaskGen.process_source` is disabled:: def build(bld): bld(rule='cp ${SRC} ${TGT}', source='wscript', target='bar.txt') """ if not getattr(self, 'rule', None): return # create the task class name = str(getattr(self, 'name', None) or self.target or getattr(self.rule, '__name__', self.rule)) # or we can put the class in a cache for performance reasons try: cache = self.bld.cache_rule_attr except AttributeError: cache = self.bld.cache_rule_attr = {} cls = None if getattr(self, 'cache_rule', 'True'): try: cls = cache[(name, self.rule)] except KeyError: pass if not cls: rule = self.rule if hasattr(self, 'chmod'): def chmod_fun(tsk): for x in tsk.outputs: os.chmod(x.abspath(), self.chmod) rule = (self.rule, chmod_fun) cls = Task.task_factory(name, rule, getattr(self, 'vars', []), shell=getattr(self, 'shell', True), color=getattr(self, 'color', 'BLUE'), scan = getattr(self, 'scan', None)) if getattr(self, 'scan', None): cls.scan = self.scan elif getattr(self, 'deps', None): def scan(self): nodes = [] for x in self.generator.to_list(getattr(self.generator, 'deps', None)): node = self.generator.path.find_resource(x) if not node: self.generator.bld.fatal('Could not find %r (was it declared?)' % x) nodes.append(node) return [nodes, []] cls.scan = scan if getattr(self, 'update_outputs', None): Task.update_outputs(cls) if getattr(self, 'always', None): Task.always_run(cls) for x in ('after', 'before', 'ext_in', 'ext_out'): setattr(cls, x, getattr(self, x, [])) if getattr(self, 'cache_rule', 'True'): cache[(name, self.rule)] = cls if getattr(self, 'cls_str', None): setattr(cls, '__str__', self.cls_str) if getattr(self, 'cls_keyword', None): setattr(cls, 'keyword', self.cls_keyword) # now create one instance tsk = self.create_task(name) if getattr(self, 'target', None): if isinstance(self.target, str): self.target = self.target.split() if not isinstance(self.target, list): self.target = [self.target] for x in self.target: if isinstance(x, str): tsk.outputs.append(self.path.find_or_declare(x)) else: x.parent.mkdir() # if a node was given, create the required folders tsk.outputs.append(x) if getattr(self, 'install_path', None): self.bld.install_files(self.install_path, tsk.outputs, chmod=getattr(self, 'chmod', Utils.O644)) if getattr(self, 'source', None): tsk.inputs = self.to_nodes(self.source) # bypass the execution of process_source by setting the source to an empty list self.source = [] if getattr(self, 'cwd', None): tsk.cwd = self.cwd @feature('seq') def sequence_order(self): """ Add a strict sequential constraint between the tasks generated by task generators. It works because task generators are posted in order. It will not post objects which belong to other folders. Example:: bld(features='javac seq') bld(features='jar seq') To start a new sequence, set the attribute seq_start, for example:: obj = bld(features='seq') obj.seq_start = True Note that the method is executed in last position. This is more an example than a widely-used solution. """ if self.meths and self.meths[-1] != 'sequence_order': self.meths.append('sequence_order') return if getattr(self, 'seq_start', None): return # all the tasks previously declared must be run before these if getattr(self.bld, 'prev', None): self.bld.prev.post() for x in self.bld.prev.tasks: for y in self.tasks: y.set_run_after(x) self.bld.prev = self re_m4 = re.compile('@(\w+)@', re.M) class subst_pc(Task.Task): """ Create *.pc* files from *.pc.in*. The task is executed whenever an input variable used in the substitution changes. """ def force_permissions(self): "Private for the time being, we will probably refactor this into run_str=[run1,chmod]" if getattr(self.generator, 'chmod', None): for x in self.outputs: os.chmod(x.abspath(), self.generator.chmod) def run(self): "Substitutes variables in a .in file" if getattr(self.generator, 'is_copy', None): for i, x in enumerate(self.outputs): x.write(self.inputs[i].read('rb'), 'wb') self.force_permissions() return None if getattr(self.generator, 'fun', None): ret = self.generator.fun(self) if not ret: self.force_permissions() return ret code = self.inputs[0].read(encoding=getattr(self.generator, 'encoding', 'ISO8859-1')) if getattr(self.generator, 'subst_fun', None): code = self.generator.subst_fun(self, code) if code is not None: self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'ISO8859-1')) self.force_permissions() return None # replace all % by %% to prevent errors by % signs code = code.replace('%', '%%') # extract the vars foo into lst and replace @foo@ by %(foo)s lst = [] def repl(match): g = match.group if g(1): lst.append(g(1)) return "%%(%s)s" % g(1) return '' global re_m4 code = getattr(self.generator, 're_m4', re_m4).sub(repl, code) try: d = self.generator.dct except AttributeError: d = {} for x in lst: tmp = getattr(self.generator, x, '') or self.env[x] or self.env[x.upper()] try: tmp = ''.join(tmp) except TypeError: tmp = str(tmp) d[x] = tmp code = code % d self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'ISO8859-1')) self.generator.bld.raw_deps[self.uid()] = self.dep_vars = lst # make sure the signature is updated try: delattr(self, 'cache_sig') except AttributeError: pass self.force_permissions() def sig_vars(self): """ Compute a hash (signature) of the variables used in the substitution """ bld = self.generator.bld env = self.env upd = self.m.update if getattr(self.generator, 'fun', None): upd(Utils.h_fun(self.generator.fun).encode()) if getattr(self.generator, 'subst_fun', None): upd(Utils.h_fun(self.generator.subst_fun).encode()) # raw_deps: persistent custom values returned by the scanner vars = self.generator.bld.raw_deps.get(self.uid(), []) # hash both env vars and task generator attributes act_sig = bld.hash_env_vars(env, vars) upd(act_sig) lst = [getattr(self.generator, x, '') for x in vars] upd(Utils.h_list(lst)) return self.m.digest() @extension('.pc.in') def add_pcfile(self, node): """ Process *.pc.in* files to *.pc*. Install the results to ``${PREFIX}/lib/pkgconfig/`` def build(bld): bld(source='foo.pc.in', install_path='${LIBDIR}/pkgconfig/') """ tsk = self.create_task('subst_pc', node, node.change_ext('.pc', '.pc.in')) self.bld.install_files(getattr(self, 'install_path', '${LIBDIR}/pkgconfig/'), tsk.outputs) class subst(subst_pc): pass @feature('subst') @before_method('process_source', 'process_rule') def process_subst(self): """ Define a transformation that substitutes the contents of *source* files to *target* files:: def build(bld): bld( features='subst', source='foo.c.in', target='foo.c', install_path='${LIBDIR}/pkgconfig', VAR = 'val' ) The input files are supposed to contain macros of the form *@VAR@*, where *VAR* is an argument of the task generator object. This method overrides the processing by :py:meth:`waflib.TaskGen.process_source`. """ src = Utils.to_list(getattr(self, 'source', [])) if isinstance(src, Node.Node): src = [src] tgt = Utils.to_list(getattr(self, 'target', [])) if isinstance(tgt, Node.Node): tgt = [tgt] if len(src) != len(tgt): raise Errors.WafError('invalid number of source/target for %r' % self) for x, y in zip(src, tgt): if not x or not y: raise Errors.WafError('null source or target for %r' % self) a, b = None, None if isinstance(x, str) and isinstance(y, str) and x == y: a = self.path.find_node(x) b = self.path.get_bld().make_node(y) if not os.path.isfile(b.abspath()): b.sig = None b.parent.mkdir() else: if isinstance(x, str): a = self.path.find_resource(x) elif isinstance(x, Node.Node): a = x if isinstance(y, str): b = self.path.find_or_declare(y) elif isinstance(y, Node.Node): b = y if not a: raise Errors.WafError('could not find %r for %r' % (x, self)) has_constraints = False tsk = self.create_task('subst', a, b) for k in ('after', 'before', 'ext_in', 'ext_out'): val = getattr(self, k, None) if val: has_constraints = True setattr(tsk, k, val) # paranoid safety measure for the general case foo.in->foo.h with ambiguous dependencies if not has_constraints: global HEADER_EXTS for xt in HEADER_EXTS: if b.name.endswith(xt): tsk.before = [k for k in ('c', 'cxx') if k in Task.classes] break inst_to = getattr(self, 'install_path', None) if inst_to: self.bld.install_files(inst_to, b, chmod=getattr(self, 'chmod', Utils.O644)) self.source = [] 1.9.12~dfsg/waflib/Errors.py0000644000000000000000000000321313214314510014431 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2010 (ita) """ Exceptions used in the Waf code """ import traceback, sys class WafError(Exception): """Base class for all Waf errors""" def __init__(self, msg='', ex=None): """ :param msg: error message :type msg: string :param ex: exception causing this error (optional) :type ex: exception """ self.msg = msg assert not isinstance(msg, Exception) self.stack = [] if ex: if not msg: self.msg = str(ex) if isinstance(ex, WafError): self.stack = ex.stack else: self.stack = traceback.extract_tb(sys.exc_info()[2]) self.stack += traceback.extract_stack()[:-1] self.verbose_msg = ''.join(traceback.format_list(self.stack)) def __str__(self): return str(self.msg) class BuildError(WafError): """ Errors raised during the build and install phases """ def __init__(self, error_tasks=[]): """ :param error_tasks: tasks that could not complete normally :type error_tasks: list of task objects """ self.tasks = error_tasks WafError.__init__(self, self.format_error()) def format_error(self): """format the error messages from the tasks that failed""" lst = ['Build failed'] for tsk in self.tasks: txt = tsk.format_error() if txt: lst.append(txt) return '\n'.join(lst) class ConfigurationError(WafError): """ Configuration exception raised in particular by :py:meth:`waflib.Context.Context.fatal` """ pass class TaskRescan(WafError): """task-specific exception type, trigger a signature recomputation""" pass class TaskNotReady(WafError): """task-specific exception type, raised when the task signature cannot be computed""" pass 1.9.12~dfsg/waflib/Utils.py0000644000000000000000000004366613214314510014275 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ Utilities and platform-specific fixes The portability fixes try to provide a consistent behavior of the Waf API through Python versions 2.3 to 3.X and across different platforms (win32, linux, etc) """ import os, sys, errno, traceback, inspect, re, shutil, datetime, gc, platform import subprocess # <- leave this! from collections import deque, defaultdict try: import _winreg as winreg except ImportError: try: import winreg except ImportError: winreg = None from waflib import Errors try: from collections import UserDict except ImportError: from UserDict import UserDict try: from hashlib import md5 except ImportError: try: from md5 import md5 except ImportError: # never fail to enable fixes from another module pass try: import threading except ImportError: if not 'JOBS' in os.environ: # no threading :-( os.environ['JOBS'] = '1' class threading(object): """ A fake threading class for platforms lacking the threading module. Use ``waf -j1`` on those platforms """ pass class Lock(object): """Fake Lock class""" def acquire(self): pass def release(self): pass threading.Lock = threading.Thread = Lock else: run_old = threading.Thread.run def run(*args, **kwargs): try: run_old(*args, **kwargs) except (KeyboardInterrupt, SystemExit): raise except Exception: sys.excepthook(*sys.exc_info()) threading.Thread.run = run SIG_NIL = 'iluvcuteoverload'.encode() """Arbitrary null value for a md5 hash. This value must be changed when the hash value is replaced (size)""" O644 = 420 """Constant representing the permissions for regular files (0644 raises a syntax error on python 3)""" O755 = 493 """Constant representing the permissions for executable files (0755 raises a syntax error on python 3)""" rot_chr = ['\\', '|', '/', '-'] "List of characters to use when displaying the throbber (progress bar)" rot_idx = 0 "Index of the current throbber character (progress bar)" try: from collections import OrderedDict as ordered_iter_dict except ImportError: class ordered_iter_dict(dict): def __init__(self, *k, **kw): self.lst = [] dict.__init__(self, *k, **kw) def clear(self): dict.clear(self) self.lst = [] def __setitem__(self, key, value): dict.__setitem__(self, key, value) try: self.lst.remove(key) except ValueError: pass self.lst.append(key) def __delitem__(self, key): dict.__delitem__(self, key) try: self.lst.remove(key) except ValueError: pass def __iter__(self): for x in self.lst: yield x def keys(self): return self.lst is_win32 = os.sep == '\\' or sys.platform == 'win32' # msys2 def readf(fname, m='r', encoding='ISO8859-1'): """ Read an entire file into a string, use this function instead of os.open() whenever possible. In practice the wrapper node.read(..) should be preferred to this function:: def build(ctx): from waflib import Utils txt = Utils.readf(self.path.find_node('wscript').abspath()) txt = ctx.path.find_node('wscript').read() :type fname: string :param fname: Path to file :type m: string :param m: Open mode :type encoding: string :param encoding: encoding value, only used for python 3 :rtype: string :return: Content of the file """ if sys.hexversion > 0x3000000 and not 'b' in m: m += 'b' f = open(fname, m) try: txt = f.read() finally: f.close() if encoding: txt = txt.decode(encoding) else: txt = txt.decode() else: f = open(fname, m) try: txt = f.read() finally: f.close() return txt def writef(fname, data, m='w', encoding='ISO8859-1'): """ Write an entire file from a string, use this function instead of os.open() whenever possible. In practice the wrapper node.write(..) should be preferred to this function:: def build(ctx): from waflib import Utils txt = Utils.writef(self.path.make_node('i_like_kittens').abspath(), 'some data') self.path.make_node('i_like_kittens').write('some data') :type fname: string :param fname: Path to file :type data: string :param data: The contents to write to the file :type m: string :param m: Open mode :type encoding: string :param encoding: encoding value, only used for python 3 """ if sys.hexversion > 0x3000000 and not 'b' in m: data = data.encode(encoding) m += 'b' f = open(fname, m) try: f.write(data) finally: f.close() def h_file(fname): """ Compute a hash value for a file by using md5. This method may be replaced by a faster version if necessary. The following uses the file size and the timestamp value:: import stat from waflib import Utils def h_file(fname): st = os.stat(fname) if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file') m = Utils.md5() m.update(str(st.st_mtime)) m.update(str(st.st_size)) m.update(fname) return m.digest() Utils.h_file = h_file :type fname: string :param fname: path to the file to hash :return: hash of the file contents """ f = open(fname, 'rb') m = md5() try: while fname: fname = f.read(200000) m.update(fname) finally: f.close() return m.digest() def readf_win32(f, m='r', encoding='ISO8859-1'): flags = os.O_NOINHERIT | os.O_RDONLY if 'b' in m: flags |= os.O_BINARY if '+' in m: flags |= os.O_RDWR try: fd = os.open(f, flags) except OSError: raise IOError('Cannot read from %r' % f) if sys.hexversion > 0x3000000 and not 'b' in m: m += 'b' f = os.fdopen(fd, m) try: txt = f.read() finally: f.close() if encoding: txt = txt.decode(encoding) else: txt = txt.decode() else: f = os.fdopen(fd, m) try: txt = f.read() finally: f.close() return txt def writef_win32(f, data, m='w', encoding='ISO8859-1'): if sys.hexversion > 0x3000000 and not 'b' in m: data = data.encode(encoding) m += 'b' flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | os.O_NOINHERIT if 'b' in m: flags |= os.O_BINARY if '+' in m: flags |= os.O_RDWR try: fd = os.open(f, flags) except OSError: raise IOError('Cannot write to %r' % f) f = os.fdopen(fd, m) try: f.write(data) finally: f.close() def h_file_win32(fname): try: fd = os.open(fname, os.O_BINARY | os.O_RDONLY | os.O_NOINHERIT) except OSError: raise IOError('Cannot read from %r' % fname) f = os.fdopen(fd, 'rb') m = md5() try: while fname: fname = f.read(200000) m.update(fname) finally: f.close() return m.digest() # always save these readf_unix = readf writef_unix = writef h_file_unix = h_file if hasattr(os, 'O_NOINHERIT') and sys.hexversion < 0x3040000: # replace the default functions readf = readf_win32 writef = writef_win32 h_file = h_file_win32 try: x = ''.encode('hex') except LookupError: import binascii def to_hex(s): ret = binascii.hexlify(s) if not isinstance(ret, str): ret = ret.decode('utf-8') return ret else: def to_hex(s): return s.encode('hex') to_hex.__doc__ = """ Return the hexadecimal representation of a string :param s: string to convert :type s: string """ def listdir_win32(s): """ List the contents of a folder in a portable manner. On Win32, return the list of drive letters: ['C:', 'X:', 'Z:'] :type s: string :param s: a string, which can be empty on Windows """ if not s: try: import ctypes except ImportError: # there is nothing much we can do return [x + ':\\' for x in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')] else: dlen = 4 # length of "?:\\x00" maxdrives = 26 buf = ctypes.create_string_buffer(maxdrives * dlen) ndrives = ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen, ctypes.byref(buf)) return [ str(buf.raw[4*i:4*i+2].decode('ascii')) for i in range(int(ndrives/dlen)) ] if len(s) == 2 and s[1] == ":": s += os.sep if not os.path.isdir(s): e = OSError('%s is not a directory' % s) e.errno = errno.ENOENT raise e return os.listdir(s) listdir = os.listdir if is_win32: listdir = listdir_win32 def num2ver(ver): """ Convert a string, tuple or version number into an integer. The number is supposed to have at most 4 digits:: from waflib.Utils import num2ver num2ver('1.3.2') == num2ver((1,3,2)) == num2ver((1,3,2,0)) :type ver: string or tuple of numbers :param ver: a version number """ if isinstance(ver, str): ver = tuple(ver.split('.')) if isinstance(ver, tuple): ret = 0 for i in range(4): if i < len(ver): ret += 256**(3 - i) * int(ver[i]) return ret return ver def ex_stack(): """ Extract the stack to display exceptions :return: a string represening the last exception """ exc_type, exc_value, tb = sys.exc_info() exc_lines = traceback.format_exception(exc_type, exc_value, tb) return ''.join(exc_lines) def to_list(sth): """ Convert a string argument to a list by splitting on spaces, and pass through a list argument unchanged:: from waflib.Utils import to_list lst = to_list("a b c d") :param sth: List or a string of items separated by spaces :rtype: list :return: Argument converted to list """ if isinstance(sth, str): return sth.split() else: return sth def split_path_unix(path): return path.split('/') def split_path_cygwin(path): if path.startswith('//'): ret = path.split('/')[2:] ret[0] = '/' + ret[0] return ret return path.split('/') re_sp = re.compile('[/\\\\]') def split_path_win32(path): if path.startswith('\\\\'): ret = re.split(re_sp, path)[2:] ret[0] = '\\' + ret[0] return ret return re.split(re_sp, path) msysroot = None def split_path_msys(path): if (path.startswith('/') or path.startswith('\\')) and not path.startswith('//') and not path.startswith('\\\\'): # msys paths can be in the form /usr/bin global msysroot if not msysroot: # msys has python 2.7 or 3, so we can use this msysroot = subprocess.check_output(['cygpath', '-w', '/']).decode(sys.stdout.encoding or 'iso8859-1') msysroot = msysroot.strip() path = os.path.normpath(msysroot + os.sep + path) return split_path_win32(path) if sys.platform == 'cygwin': split_path = split_path_cygwin elif is_win32: if os.environ.get('MSYSTEM', None): split_path = split_path_msys else: split_path = split_path_win32 else: split_path = split_path_unix split_path.__doc__ = """ Split a path by / or \\. This function is not like os.path.split :type path: string :param path: path to split :return: list of strings """ def check_dir(path): """ Ensure that a directory exists (similar to ``mkdir -p``). :type path: string :param path: Path to directory """ if not os.path.isdir(path): try: os.makedirs(path) except OSError as e: if not os.path.isdir(path): raise Errors.WafError('Cannot create the folder %r' % path, ex=e) def check_exe(name, env=None): """ Ensure that a program exists :type name: string :param name: name or path to program :return: path of the program or None """ if not name: raise ValueError('Cannot execute an empty string!') def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) fpath, fname = os.path.split(name) if fpath and is_exe(name): return os.path.abspath(name) else: env = env or os.environ for path in env["PATH"].split(os.pathsep): path = path.strip('"') exe_file = os.path.join(path, name) if is_exe(exe_file): return os.path.abspath(exe_file) return None def def_attrs(cls, **kw): """ Set default attributes on a class instance :type cls: class :param cls: the class to update the given attributes in. :type kw: dict :param kw: dictionary of attributes names and values. """ for k, v in kw.items(): if not hasattr(cls, k): setattr(cls, k, v) def quote_define_name(s): """ Convert a string to an identifier suitable for C defines. :type s: string :param s: String to convert :rtype: string :return: Identifier suitable for C defines """ fu = re.sub('[^a-zA-Z0-9]', '_', s) fu = re.sub('_+', '_', fu) fu = fu.upper() return fu def h_list(lst): """ Hash lists. For tuples, using hash(tup) is much more efficient, except on python >= 3.3 where hash randomization assumes everybody is running a web application. :param lst: list to hash :type lst: list of strings :return: hash of the list """ m = md5() m.update(str(lst).encode()) return m.digest() def h_fun(fun): """ Hash functions :param fun: function to hash :type fun: function :return: hash of the function """ try: return fun.code except AttributeError: try: h = inspect.getsource(fun) except IOError: h = "nocode" try: fun.code = h except AttributeError: pass return h def h_cmd(ins): """ Task command hashes are calculated by calling this function. The inputs can be strings, functions, tuples/lists containing strings/functions """ # this function is not meant to be particularly fast if isinstance(ins, str): # a command is either a string ret = ins elif isinstance(ins, list) or isinstance(ins, tuple): # or a list of functions/strings ret = str([h_cmd(x) for x in ins]) else: # or just a python function ret = str(h_fun(ins)) if sys.hexversion > 0x3000000: ret = ret.encode('iso8859-1', 'xmlcharrefreplace') return ret reg_subst = re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}") def subst_vars(expr, params): """ Replace ${VAR} with the value of VAR taken from a dict or a config set:: from waflib import Utils s = Utils.subst_vars('${PREFIX}/bin', env) :type expr: string :param expr: String to perform substitution on :param params: Dictionary or config set to look up variable values. """ def repl_var(m): if m.group(1): return '\\' if m.group(2): return '$' try: # ConfigSet instances may contain lists return params.get_flat(m.group(3)) except AttributeError: return params[m.group(3)] # if you get a TypeError, it means that 'expr' is not a string... # Utils.subst_vars(None, env) will not work return reg_subst.sub(repl_var, expr) def destos_to_binfmt(key): """ Return the binary format based on the unversioned platform name. :param key: platform name :type key: string :return: string representing the binary format """ if key == 'darwin': return 'mac-o' elif key in ('win32', 'cygwin', 'uwin', 'msys'): return 'pe' return 'elf' def unversioned_sys_platform(): """ Return the unversioned platform name. Some Python platform names contain versions, that depend on the build environment, e.g. linux2, freebsd6, etc. This returns the name without the version number. Exceptions are os2 and win32, which are returned verbatim. :rtype: string :return: Unversioned platform name """ s = sys.platform if s.startswith('java'): # The real OS is hidden under the JVM. from java.lang import System s = System.getProperty('os.name') # see http://lopica.sourceforge.net/os.html for a list of possible values if s == 'Mac OS X': return 'darwin' elif s.startswith('Windows '): return 'win32' elif s == 'OS/2': return 'os2' elif s == 'HP-UX': return 'hp-ux' elif s in ('SunOS', 'Solaris'): return 'sunos' else: s = s.lower() # powerpc == darwin for our purposes if s == 'powerpc': return 'darwin' if s == 'win32' or s == 'os2': return s if s == 'cli' and os.name == 'nt': # ironpython is only on windows as far as we know return 'win32' return re.split('\d+$', s)[0] def nada(*k, **kw): """ A function that does nothing :return: None """ pass class Timer(object): """ Simple object for timing the execution of commands. Its string representation is the current time:: from waflib.Utils import Timer timer = Timer() a_few_operations() s = str(timer) """ def __init__(self): self.start_time = datetime.datetime.utcnow() def __str__(self): delta = datetime.datetime.utcnow() - self.start_time days = delta.days hours, rem = divmod(delta.seconds, 3600) minutes, seconds = divmod(rem, 60) seconds += delta.microseconds * 1e-6 result = '' if days: result += '%dd' % days if days or hours: result += '%dh' % hours if days or hours or minutes: result += '%dm' % minutes return '%s%.3fs' % (result, seconds) if is_win32: old = shutil.copy2 def copy2(src, dst): """ shutil.copy2 does not copy the file attributes on windows, so we hack into the shutil module to fix the problem """ old(src, dst) shutil.copystat(src, dst) setattr(shutil, 'copy2', copy2) if os.name == 'java': # Jython cannot disable the gc but they can enable it ... wtf? try: gc.disable() gc.enable() except NotImplementedError: gc.disable = gc.enable def read_la_file(path): """ Read property files, used by msvc.py :param path: file to read :type path: string """ sp = re.compile(r'^([^=]+)=\'(.*)\'$') dc = {} for line in readf(path).splitlines(): try: _, left, right, _ = sp.split(line.strip()) dc[left] = right except ValueError: pass return dc def nogc(fun): """ Decorator: let a function disable the garbage collector during its execution. It is used in the build context when storing/loading the build cache file (pickle) :param fun: function to execute :type fun: function :return: the return value of the function executed """ def f(*k, **kw): try: gc.disable() ret = fun(*k, **kw) finally: gc.enable() return ret f.__doc__ = fun.__doc__ return f def run_once(fun): """ Decorator: let a function cache its results, use like this:: @run_once def foo(k): return 345*2343 :param fun: function to execute :type fun: function :return: the return value of the function executed """ cache = {} def wrap(k): try: return cache[k] except KeyError: ret = fun(k) cache[k] = ret return ret wrap.__cache__ = cache wrap.__name__ = fun.__name__ return wrap def get_registry_app_path(key, filename): if not winreg: return None try: result = winreg.QueryValue(key, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe" % filename[0]) except WindowsError: pass else: if os.path.isfile(result): return result def lib64(): # default settings for /usr/lib if os.sep == '/': if platform.architecture()[0] == '64bit': if os.path.exists('/usr/lib64') and not os.path.exists('/usr/lib32'): return '64' return '' def sane_path(p): # private function for the time being! return os.path.abspath(os.path.expanduser(p)) 1.9.12~dfsg/waflib/Options.py0000644000000000000000000002115313214314510014613 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Scott Newton, 2005 (scottn) # Thomas Nagy, 2006-2010 (ita) """ Support for waf command-line options Provides default command-line options, as well as custom ones, used by the ``options`` wscript function. """ import os, tempfile, optparse, sys, re from waflib import Logs, Utils, Context cmds = 'distclean configure build install clean uninstall check dist distcheck'.split() """ Constant representing the default waf commands displayed in:: $ waf --help """ options = {} """ A dictionary representing the command-line options:: $ waf --foo=bar """ commands = [] """ List of commands to execute extracted from the command-line. This list is consumed during the execution, see :py:func:`waflib.Scripting.run_commands`. """ envvars = [] """ List of environment variable declarations placed after the Waf executable name. These are detected by searching for "=" in the rest arguments. """ lockfile = os.environ.get('WAFLOCK', '.lock-waf_%s_build' % sys.platform) platform = Utils.unversioned_sys_platform() class opt_parser(optparse.OptionParser): """ Command-line options parser. """ def __init__(self, ctx): optparse.OptionParser.__init__(self, conflict_handler="resolve", version='waf %s (%s)' % (Context.WAFVERSION, Context.WAFREVISION)) self.formatter.width = Logs.get_term_cols() self.ctx = ctx def print_usage(self, file=None): return self.print_help(file) def get_usage(self): """ Return the message to print on ``waf --help`` """ cmds_str = {} for cls in Context.classes: if not cls.cmd or cls.cmd == 'options' or cls.cmd.startswith( '_' ): continue s = cls.__doc__ or '' cmds_str[cls.cmd] = s if Context.g_module: for (k, v) in Context.g_module.__dict__.items(): if k in ('options', 'init', 'shutdown'): continue if type(v) is type(Context.create_context): if v.__doc__ and not k.startswith('_'): cmds_str[k] = v.__doc__ just = 0 for k in cmds_str: just = max(just, len(k)) lst = [' %s: %s' % (k.ljust(just), v) for (k, v) in cmds_str.items()] lst.sort() ret = '\n'.join(lst) return '''waf [commands] [options] Main commands (example: ./waf build -j4) %s ''' % ret class OptionsContext(Context.Context): """ Collect custom options from wscript files and parses the command line. Set the global :py:const:`waflib.Options.commands` and :py:const:`waflib.Options.options` values. """ cmd = 'options' fun = 'options' def __init__(self, **kw): super(OptionsContext, self).__init__(**kw) self.parser = opt_parser(self) """Instance of :py:class:`waflib.Options.opt_parser`""" self.option_groups = {} jobs = self.jobs() p = self.add_option color = os.environ.get('NOCOLOR', '') and 'no' or 'auto' p('-c', '--color', dest='colors', default=color, action='store', help='whether to use colors (yes/no/auto) [default: auto]', choices=('yes', 'no', 'auto')) p('-j', '--jobs', dest='jobs', default=jobs, type='int', help='amount of parallel jobs (%r)' % jobs) p('-k', '--keep', dest='keep', default=0, action='count', help='continue despite errors (-kk to try harder)') p('-v', '--verbose', dest='verbose', default=0, action='count', help='verbosity level -v -vv or -vvv [default: 0]') p('--zones', dest='zones', default='', action='store', help='debugging zones (task_gen, deps, tasks, etc)') gr = self.add_option_group('Configuration options') self.option_groups['configure options'] = gr gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out') gr.add_option('-t', '--top', action='store', default='', help='src dir for the project', dest='top') gr.add_option('--no-lock-in-run', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_run') gr.add_option('--no-lock-in-out', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_out') gr.add_option('--no-lock-in-top', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_top') default_prefix = getattr(Context.g_module, 'default_prefix', os.environ.get('PREFIX')) if not default_prefix: if platform == 'win32': d = tempfile.gettempdir() default_prefix = d[0].upper() + d[1:] # win32 preserves the case, but gettempdir does not else: default_prefix = '/usr/local/' gr.add_option('--prefix', dest='prefix', default=default_prefix, help='installation prefix [default: %r]' % default_prefix) gr.add_option('--bindir', dest='bindir', help='bindir') gr.add_option('--libdir', dest='libdir', help='libdir') gr = self.add_option_group('Build and installation options') self.option_groups['build and install options'] = gr gr.add_option('-p', '--progress', dest='progress_bar', default=0, action='count', help= '-p: progress bar; -pp: ide output') gr.add_option('--targets', dest='targets', default='', action='store', help='task generators, e.g. "target1,target2"') gr = self.add_option_group('Step options') self.option_groups['step options'] = gr gr.add_option('--files', dest='files', default='', action='store', help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"') default_destdir = os.environ.get('DESTDIR', '') gr = self.add_option_group('Installation and uninstallation options') self.option_groups['install/uninstall options'] = gr gr.add_option('--destdir', help='installation root [default: %r]' % default_destdir, default=default_destdir, dest='destdir') gr.add_option('-f', '--force', dest='force', default=False, action='store_true', help='force file installation') gr.add_option('--distcheck-args', metavar='ARGS', help='arguments to pass to distcheck', default=None, action='store') def jobs(self): """ Find the amount of cpu cores to set the default amount of tasks executed in parallel. At runtime the options can be obtained from :py:const:`waflib.Options.options` :: from waflib.Options import options njobs = options.jobs :return: the amount of cpu cores :rtype: int """ count = int(os.environ.get('JOBS', 0)) if count < 1: if 'NUMBER_OF_PROCESSORS' in os.environ: # on Windows, use the NUMBER_OF_PROCESSORS environment variable count = int(os.environ.get('NUMBER_OF_PROCESSORS', 1)) else: # on everything else, first try the POSIX sysconf values if hasattr(os, 'sysconf_names'): if 'SC_NPROCESSORS_ONLN' in os.sysconf_names: count = int(os.sysconf('SC_NPROCESSORS_ONLN')) elif 'SC_NPROCESSORS_CONF' in os.sysconf_names: count = int(os.sysconf('SC_NPROCESSORS_CONF')) if not count and os.name not in ('nt', 'java'): try: tmp = self.cmd_and_log(['sysctl', '-n', 'hw.ncpu'], quiet=0) except Exception: pass else: if re.match('^[0-9]+$', tmp): count = int(tmp) if count < 1: count = 1 elif count > 1024: count = 1024 return count def add_option(self, *k, **kw): """ Wrapper for optparse.add_option:: def options(ctx): ctx.add_option('-u', '--use', dest='use', default=False, action='store_true', help='a boolean option') """ return self.parser.add_option(*k, **kw) def add_option_group(self, *k, **kw): """ Wrapper for optparse.add_option_group:: def options(ctx): gr = ctx.add_option_group('some options') gr.add_option('-u', '--use', dest='use', default=False, action='store_true') """ try: gr = self.option_groups[k[0]] except KeyError: gr = self.parser.add_option_group(*k, **kw) self.option_groups[k[0]] = gr return gr def get_option_group(self, opt_str): """ Wrapper for optparse.get_option_group:: def options(ctx): gr = ctx.get_option_group('configure options') gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out') """ try: return self.option_groups[opt_str] except KeyError: for group in self.parser.option_groups: if group.title == opt_str: return group return None def parse_args(self, _args=None): """ Parse arguments from a list (not bound to the command-line). :param _args: arguments :type _args: list of strings """ global options, commands, envvars (options, leftover_args) = self.parser.parse_args(args=_args) for arg in leftover_args: if '=' in arg: envvars.append(arg) else: commands.append(arg) if options.destdir: options.destdir = Utils.sane_path(options.destdir) if options.verbose >= 1: self.load('errcheck') colors = {'yes' : 2, 'auto' : 1, 'no' : 0}[options.colors] Logs.enable_colors(colors) def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ super(OptionsContext, self).execute() self.parse_args() 1.9.12~dfsg/waflib/Build.py0000644000000000000000000011170713214314510014224 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ Classes related to the build phase (build, clean, install, step, etc) The inheritance tree is the following: """ import os, sys, errno, re, shutil, stat try: import cPickle except ImportError: import pickle as cPickle from waflib import Runner, TaskGen, Utils, ConfigSet, Task, Logs, Options, Context, Errors import waflib.Node CACHE_DIR = 'c4che' """Location of the cache files""" CACHE_SUFFIX = '_cache.py' """Suffix for the cache files""" INSTALL = 1337 """Positive value '->' install, see :py:attr:`waflib.Build.BuildContext.is_install`""" UNINSTALL = -1337 """Negative value '<-' uninstall, see :py:attr:`waflib.Build.BuildContext.is_install`""" SAVED_ATTRS = 'root node_deps raw_deps task_sigs'.split() """Build class members to save between the runs (root, node_deps, raw_deps, task_sigs)""" CFG_FILES = 'cfg_files' """Files from the build directory to hash before starting the build (``config.h`` written during the configuration)""" POST_AT_ONCE = 0 """Post mode: all task generators are posted before the build really starts""" POST_LAZY = 1 """Post mode: post the task generators group after group""" POST_BOTH = 2 """Post mode: post the task generators at once, then re-check them for each group""" PROTOCOL = -1 if sys.platform == 'cli': PROTOCOL = 0 class BuildContext(Context.Context): '''executes the build''' cmd = 'build' variant = '' def __init__(self, **kw): super(BuildContext, self).__init__(**kw) self.is_install = 0 """Non-zero value when installing or uninstalling file""" self.top_dir = kw.get('top_dir', Context.top_dir) self.run_dir = kw.get('run_dir', Context.run_dir) self.post_mode = POST_AT_ONCE """post the task generators at once, group-by-group, or both""" # output directory - may be set until the nodes are considered self.out_dir = kw.get('out_dir', Context.out_dir) self.cache_dir = kw.get('cache_dir', None) if not self.cache_dir: self.cache_dir = os.path.join(self.out_dir, CACHE_DIR) # map names to environments, the '' must be defined self.all_envs = {} # ======================================= # # cache variables self.task_sigs = {} """Signatures of the tasks (persists between build executions)""" self.node_deps = {} """Dict of node dependencies found by :py:meth:`waflib.Task.Task.scan` (persists between build executions)""" self.raw_deps = {} """Dict of custom data returned by :py:meth:`waflib.Task.Task.scan` (persists between build executions)""" # list of folders that are already scanned # so that we do not need to stat them one more time self.cache_dir_contents = {} self.task_gen_cache_names = {} self.launch_dir = Context.launch_dir self.jobs = Options.options.jobs self.targets = Options.options.targets self.keep = Options.options.keep self.progress_bar = Options.options.progress_bar ############ stuff below has not been reviewed # Manual dependencies. self.deps_man = Utils.defaultdict(list) """Manual dependencies set by :py:meth:`waflib.Build.BuildContext.add_manual_dependency`""" # just the structure here self.current_group = 0 """ Current build group """ self.groups = [] """ List containing lists of task generators """ self.group_names = {} """ Map group names to the group lists. See :py:meth:`waflib.Build.BuildContext.add_group` """ def get_variant_dir(self): """Getter for the variant_dir attribute""" if not self.variant: return self.out_dir return os.path.join(self.out_dir, self.variant) variant_dir = property(get_variant_dir, None) def __call__(self, *k, **kw): """ Create a task generator and add it to the current build group. The following forms are equivalent:: def build(bld): tg = bld(a=1, b=2) def build(bld): tg = bld() tg.a = 1 tg.b = 2 def build(bld): tg = TaskGen.task_gen(a=1, b=2) bld.add_to_group(tg, None) :param group: group name to add the task generator to :type group: string """ kw['bld'] = self ret = TaskGen.task_gen(*k, **kw) self.task_gen_cache_names = {} # reset the cache, each time self.add_to_group(ret, group=kw.get('group', None)) return ret def rule(self, *k, **kw): """ Wrapper for creating a task generator using the decorator notation. The following code:: @bld.rule( target = "foo" ) def _(tsk): print("bar") is equivalent to:: def bar(tsk): print("bar") bld( target = "foo", rule = bar, ) """ def f(rule): ret = self(*k, **kw) ret.rule = rule return ret return f def __copy__(self): """Implemented to prevents copies of build contexts (raises an exception)""" raise Errors.WafError('build contexts are not supposed to be copied') def install_files(self, *k, **kw): """Actual implementation provided by :py:meth:`waflib.Build.InstallContext.install_files`""" pass def install_as(self, *k, **kw): """Actual implementation provided by :py:meth:`waflib.Build.InstallContext.install_as`""" pass def symlink_as(self, *k, **kw): """Actual implementation provided by :py:meth:`waflib.Build.InstallContext.symlink_as`""" pass def load_envs(self): """ The configuration command creates files of the form ``build/c4che/NAMEcache.py``. This method creates a :py:class:`waflib.ConfigSet.ConfigSet` instance for each ``NAME`` by reading those files. The config sets are then stored in the dict :py:attr:`waflib.Build.BuildContext.allenvs`. """ node = self.root.find_node(self.cache_dir) if not node: raise Errors.WafError('The project was not configured: run "waf configure" first!') lst = node.ant_glob('**/*%s' % CACHE_SUFFIX, quiet=True) if not lst: raise Errors.WafError('The cache directory is empty: reconfigure the project') for x in lst: name = x.path_from(node).replace(CACHE_SUFFIX, '').replace('\\', '/') env = ConfigSet.ConfigSet(x.abspath()) self.all_envs[name] = env for f in env[CFG_FILES]: newnode = self.root.find_resource(f) try: h = Utils.h_file(newnode.abspath()) except (IOError, AttributeError): Logs.error('cannot find %r' % f) h = Utils.SIG_NIL newnode.sig = h def init_dirs(self): """ Initialize the project directory and the build directory by creating the nodes :py:attr:`waflib.Build.BuildContext.srcnode` and :py:attr:`waflib.Build.BuildContext.bldnode` corresponding to ``top_dir`` and ``variant_dir`` respectively. The ``bldnode`` directory will be created if it does not exist. """ if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)): raise Errors.WafError('The project was not configured: run "waf configure" first!') self.path = self.srcnode = self.root.find_dir(self.top_dir) self.bldnode = self.root.make_node(self.variant_dir) self.bldnode.mkdir() def execute(self): """ Restore the data from previous builds and call :py:meth:`waflib.Build.BuildContext.execute_build`. Overrides from :py:func:`waflib.Context.Context.execute` """ self.restore() if not self.all_envs: self.load_envs() self.execute_build() def execute_build(self): """ Execute the build by: * reading the scripts (see :py:meth:`waflib.Context.Context.recurse`) * calling :py:meth:`waflib.Build.BuildContext.pre_build` to call user build functions * calling :py:meth:`waflib.Build.BuildContext.compile` to process the tasks * calling :py:meth:`waflib.Build.BuildContext.post_build` to call user build functions """ Logs.info("Waf: Entering directory `%s'" % self.variant_dir) self.recurse([self.run_dir]) self.pre_build() # display the time elapsed in the progress bar self.timer = Utils.Timer() try: self.compile() finally: if self.progress_bar == 1 and sys.stderr.isatty(): c = len(self.returned_tasks) or 1 m = self.progress_line(c, c, Logs.colors.BLUE, Logs.colors.NORMAL) Logs.info(m, extra={'stream': sys.stderr, 'c1': Logs.colors.cursor_off, 'c2' : Logs.colors.cursor_on}) Logs.info("Waf: Leaving directory `%s'" % self.variant_dir) self.post_build() def restore(self): """ Load the data from a previous run, sets the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS` """ try: env = ConfigSet.ConfigSet(os.path.join(self.cache_dir, 'build.config.py')) except EnvironmentError: pass else: if env['version'] < Context.HEXVERSION: raise Errors.WafError('Version mismatch! reconfigure the project') for t in env['tools']: self.setup(**t) dbfn = os.path.join(self.variant_dir, Context.DBFILE) try: data = Utils.readf(dbfn, 'rb') except (IOError, EOFError): # handle missing file/empty file Logs.debug('build: Could not load the build cache %s (missing)' % dbfn) else: try: waflib.Node.pickle_lock.acquire() waflib.Node.Nod3 = self.node_class try: data = cPickle.loads(data) except Exception as e: Logs.debug('build: Could not pickle the build cache %s: %r' % (dbfn, e)) else: for x in SAVED_ATTRS: setattr(self, x, data[x]) finally: waflib.Node.pickle_lock.release() self.init_dirs() def store(self): """ Store the data for next runs, sets the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS`. Uses a temporary file to avoid problems on ctrl+c. """ data = {} for x in SAVED_ATTRS: data[x] = getattr(self, x) db = os.path.join(self.variant_dir, Context.DBFILE) try: waflib.Node.pickle_lock.acquire() waflib.Node.Nod3 = self.node_class x = cPickle.dumps(data, PROTOCOL) finally: waflib.Node.pickle_lock.release() Utils.writef(db + '.tmp', x, m='wb') try: st = os.stat(db) os.remove(db) if not Utils.is_win32: # win32 has no chown but we're paranoid os.chown(db + '.tmp', st.st_uid, st.st_gid) except (AttributeError, OSError): pass # do not use shutil.move (copy is not thread-safe) os.rename(db + '.tmp', db) def compile(self): """ Run the build by creating an instance of :py:class:`waflib.Runner.Parallel` The cache file is not written if the build is up to date (no task executed). """ Logs.debug('build: compile()') # use another object to perform the producer-consumer logic (reduce the complexity) self.producer = Runner.Parallel(self, self.jobs) self.producer.biter = self.get_build_iterator() self.returned_tasks = [] # not part of the API yet try: self.producer.start() except KeyboardInterrupt: self.store() raise else: if self.producer.dirty: self.store() if self.producer.error: raise Errors.BuildError(self.producer.error) def setup(self, tool, tooldir=None, funs=None): """ Import waf tools, used to import those accessed during the configuration:: def configure(conf): conf.load('glib2') def build(bld): pass # glib2 is imported implicitly :param tool: tool list :type tool: list :param tooldir: optional tool directory (sys.path) :type tooldir: list of string :param funs: unused variable """ if isinstance(tool, list): for i in tool: self.setup(i, tooldir) return module = Context.load_tool(tool, tooldir) if hasattr(module, "setup"): module.setup(self) def get_env(self): """Getter for the env property""" try: return self.all_envs[self.variant] except KeyError: return self.all_envs[''] def set_env(self, val): """Setter for the env property""" self.all_envs[self.variant] = val env = property(get_env, set_env) def add_manual_dependency(self, path, value): """ Adds a dependency from a node object to a value:: def build(bld): bld.add_manual_dependency( bld.path.find_resource('wscript'), bld.root.find_resource('/etc/fstab')) :param path: file path :type path: string or :py:class:`waflib.Node.Node` :param value: value to depend on :type value: :py:class:`waflib.Node.Node`, string, or function returning a string """ if path is None: raise ValueError('Invalid input') if isinstance(path, waflib.Node.Node): node = path elif os.path.isabs(path): node = self.root.find_resource(path) else: node = self.path.find_resource(path) if isinstance(value, list): self.deps_man[id(node)].extend(value) else: self.deps_man[id(node)].append(value) def launch_node(self): """Returns the launch directory as a :py:class:`waflib.Node.Node` object""" try: # private cache return self.p_ln except AttributeError: self.p_ln = self.root.find_dir(self.launch_dir) return self.p_ln def hash_env_vars(self, env, vars_lst): """ Hash configuration set variables:: def build(bld): bld.hash_env_vars(bld.env, ['CXX', 'CC']) :param env: Configuration Set :type env: :py:class:`waflib.ConfigSet.ConfigSet` :param vars_lst: list of variables :type vars_list: list of string """ if not env.table: env = env.parent if not env: return Utils.SIG_NIL idx = str(id(env)) + str(vars_lst) try: cache = self.cache_env except AttributeError: cache = self.cache_env = {} else: try: return self.cache_env[idx] except KeyError: pass lst = [env[a] for a in vars_lst] ret = Utils.h_list(lst) Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst) cache[idx] = ret return ret def get_tgen_by_name(self, name): """ Retrieves a task generator from its name or its target name the name must be unique:: def build(bld): tg = bld(name='foo') tg == bld.get_tgen_by_name('foo') """ cache = self.task_gen_cache_names if not cache: # create the index lazily for g in self.groups: for tg in g: try: cache[tg.name] = tg except AttributeError: # raised if not a task generator, which should be uncommon pass try: return cache[name] except KeyError: raise Errors.WafError('Could not find a task generator for the name %r' % name) def progress_line(self, state, total, col1, col2): """ Compute the progress bar used by ``waf -p`` """ if not sys.stderr.isatty(): return '' n = len(str(total)) Utils.rot_idx += 1 ind = Utils.rot_chr[Utils.rot_idx % 4] pc = (100.*state)/total eta = str(self.timer) fs = "[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s][" % (n, n, ind) left = fs % (state, total, col1, pc, col2) right = '][%s%s%s]' % (col1, eta, col2) cols = Logs.get_term_cols() - len(left) - len(right) + 2*len(col1) + 2*len(col2) if cols < 7: cols = 7 ratio = ((cols*state)//total) - 1 bar = ('='*ratio+'>').ljust(cols) msg = Logs.indicator % (left, bar, right) return msg def declare_chain(self, *k, **kw): """ Wrapper for :py:func:`waflib.TaskGen.declare_chain` provided for convenience """ return TaskGen.declare_chain(*k, **kw) def pre_build(self): """Execute user-defined methods before the build starts, see :py:meth:`waflib.Build.BuildContext.add_pre_fun`""" for m in getattr(self, 'pre_funs', []): m(self) def post_build(self): """Executes the user-defined methods after the build is successful, see :py:meth:`waflib.Build.BuildContext.add_post_fun`""" for m in getattr(self, 'post_funs', []): m(self) def add_pre_fun(self, meth): """ Bind a method to execute after the scripts are read and before the build starts:: def mycallback(bld): print("Hello, world!") def build(bld): bld.add_pre_fun(mycallback) """ try: self.pre_funs.append(meth) except AttributeError: self.pre_funs = [meth] def add_post_fun(self, meth): """ Bind a method to execute immediately after the build is successful:: def call_ldconfig(bld): bld.exec_command('/sbin/ldconfig') def build(bld): if bld.cmd == 'install': bld.add_pre_fun(call_ldconfig) """ try: self.post_funs.append(meth) except AttributeError: self.post_funs = [meth] def get_group(self, x): """ Get the group x, or return the current group if x is None :param x: name or number or None :type x: string, int or None """ if not self.groups: self.add_group() if x is None: return self.groups[self.current_group] if x in self.group_names: return self.group_names[x] return self.groups[x] def add_to_group(self, tgen, group=None): """add a task or a task generator for the build""" # paranoid assert(isinstance(tgen, TaskGen.task_gen) or isinstance(tgen, Task.TaskBase)) tgen.bld = self self.get_group(group).append(tgen) def get_group_name(self, g): """name for the group g (utility)""" if not isinstance(g, list): g = self.groups[g] for x in self.group_names: if id(self.group_names[x]) == id(g): return x return '' def get_group_idx(self, tg): """ Index of the group containing the task generator given as argument:: def build(bld): tg = bld(name='nada') 0 == bld.get_group_idx(tg) :param tg: Task generator object :type tg: :py:class:`waflib.TaskGen.task_gen` """ se = id(tg) for i in range(len(self.groups)): for t in self.groups[i]: if id(t) == se: return i return None def add_group(self, name=None, move=True): """ Add a new group of tasks/task generators. By default the new group becomes the default group for new task generators. :param name: name for this group :type name: string :param move: set the group created as default group (True by default) :type move: bool """ #if self.groups and not self.groups[0].tasks: # error('add_group: an empty group is already present') if name and name in self.group_names: Logs.error('add_group: name %s already present' % name) g = [] self.group_names[name] = g self.groups.append(g) if move: self.current_group = len(self.groups) - 1 def set_group(self, idx): """ Set the current group to be idx: now new task generators will be added to this group by default:: def build(bld): bld(rule='touch ${TGT}', target='foo.txt') bld.add_group() # now the current group is 1 bld(rule='touch ${TGT}', target='bar.txt') bld.set_group(0) # now the current group is 0 bld(rule='touch ${TGT}', target='truc.txt') # build truc.txt before bar.txt :param idx: group name or group index :type idx: string or int """ if isinstance(idx, str): g = self.group_names[idx] for i in range(len(self.groups)): if id(g) == id(self.groups[i]): self.current_group = i break else: self.current_group = idx def total(self): """ Approximate task count: this value may be inaccurate if task generators are posted lazily (see :py:attr:`waflib.Build.BuildContext.post_mode`). The value :py:attr:`waflib.Runner.Parallel.total` is updated during the task execution. """ total = 0 for group in self.groups: for tg in group: try: total += len(tg.tasks) except AttributeError: total += 1 return total def get_targets(self): """ Return the task generator corresponding to the 'targets' list, used by :py:meth:`waflib.Build.BuildContext.get_build_iterator`:: $ waf --targets=myprogram,myshlib """ to_post = [] min_grp = 0 for name in self.targets.split(','): tg = self.get_tgen_by_name(name) m = self.get_group_idx(tg) if m > min_grp: min_grp = m to_post = [tg] elif m == min_grp: to_post.append(tg) return (min_grp, to_post) def get_all_task_gen(self): """ Utility method, returns a list of all task generators - if you need something more complicated, implement your own """ lst = [] for g in self.groups: lst.extend(g) return lst def post_group(self): """ Post the task generators from the group indexed by self.cur, used by :py:meth:`waflib.Build.BuildContext.get_build_iterator` """ if self.targets == '*': for tg in self.groups[self.cur]: try: f = tg.post except AttributeError: pass else: f() elif self.targets: if self.cur < self._min_grp: for tg in self.groups[self.cur]: try: f = tg.post except AttributeError: pass else: f() else: for tg in self._exact_tg: tg.post() else: ln = self.launch_node() if ln.is_child_of(self.bldnode): Logs.warn('Building from the build directory, forcing --targets=*') ln = self.srcnode elif not ln.is_child_of(self.srcnode): Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)' % (ln.abspath(), self.srcnode.abspath())) ln = self.srcnode for tg in self.groups[self.cur]: try: f = tg.post except AttributeError: pass else: if tg.path.is_child_of(ln): f() def get_tasks_group(self, idx): """ Return all the tasks for the group of num idx, used by :py:meth:`waflib.Build.BuildContext.get_build_iterator` """ tasks = [] for tg in self.groups[idx]: try: tasks.extend(tg.tasks) except AttributeError: # not a task generator, can be the case for installation tasks tasks.append(tg) return tasks def get_build_iterator(self): """ Creates a generator object that returns lists of tasks executable in parallel (yield) :return: tasks which can be executed immediatly :rtype: list of :py:class:`waflib.Task.TaskBase` """ self.cur = 0 if self.targets and self.targets != '*': (self._min_grp, self._exact_tg) = self.get_targets() global lazy_post if self.post_mode != POST_LAZY: while self.cur < len(self.groups): self.post_group() self.cur += 1 self.cur = 0 while self.cur < len(self.groups): # first post the task generators for the group if self.post_mode != POST_AT_ONCE: self.post_group() # then extract the tasks tasks = self.get_tasks_group(self.cur) # if the constraints are set properly (ext_in/ext_out, before/after) # the call to set_file_constraints may be removed (can be a 15% penalty on no-op rebuilds) # (but leave set_file_constraints for the installation step) # # if the tasks have only files, set_file_constraints is required but set_precedence_constraints is not necessary # Task.set_file_constraints(tasks) Task.set_precedence_constraints(tasks) self.cur_tasks = tasks self.cur += 1 if not tasks: # return something else the build will stop continue yield tasks while 1: yield [] class inst(Task.Task): """ Special task used for installing files and symlinks, it behaves both like a task and like a task generator """ color = 'CYAN' def uid(self): lst = [self.dest, self.path] + self.source return Utils.h_list(repr(lst)) def post(self): """ Same interface as in :py:meth:`waflib.TaskGen.task_gen.post` """ buf = [] for x in self.source: if isinstance(x, waflib.Node.Node): y = x else: y = self.path.find_resource(x) if not y: if os.path.isabs(x): y = self.bld.root.make_node(x) else: y = self.path.make_node(x) buf.append(y) self.inputs = buf def runnable_status(self): """ Installation tasks are always executed, so this method returns either :py:const:`waflib.Task.ASK_LATER` or :py:const:`waflib.Task.RUN_ME`. """ ret = super(inst, self).runnable_status() if ret == Task.SKIP_ME: return Task.RUN_ME return ret def __str__(self): """Return an empty string to disable the display""" return '' def run(self): """The attribute 'exec_task' holds the method to execute""" return self.generator.exec_task() def get_install_path(self, destdir=True): """ Installation path obtained from ``self.dest`` and prefixed by the destdir. The variables such as '${PREFIX}/bin' are substituted. """ dest = Utils.subst_vars(self.dest, self.env) dest = dest.replace('/', os.sep) if destdir and Options.options.destdir: dest = os.path.join(Options.options.destdir, os.path.splitdrive(dest)[1].lstrip(os.sep)) return dest def exec_install_files(self): """ Predefined method for installing files """ destpath = self.get_install_path() if not destpath: raise Errors.WafError('unknown installation path %r' % self.generator) for x, y in zip(self.source, self.inputs): if self.relative_trick: destfile = os.path.join(destpath, y.path_from(self.path)) else: destfile = os.path.join(destpath, y.name) self.generator.bld.do_install(y.abspath(), destfile, chmod=self.chmod, tsk=self) def exec_install_as(self): """ Predefined method for installing one file with a given name """ destfile = self.get_install_path() self.generator.bld.do_install(self.inputs[0].abspath(), destfile, chmod=self.chmod, tsk=self) def exec_symlink_as(self): """ Predefined method for installing a symlink """ destfile = self.get_install_path() src = self.link if self.relative_trick: src = os.path.relpath(src, os.path.dirname(destfile)) self.generator.bld.do_link(src, destfile, tsk=self) class InstallContext(BuildContext): '''installs the targets on the system''' cmd = 'install' def __init__(self, **kw): super(InstallContext, self).__init__(**kw) # list of targets to uninstall for removing the empty folders after uninstalling self.uninstall = [] self.is_install = INSTALL def copy_fun(self, src, tgt, **kw): # override this if you want to strip executables # kw['tsk'].source is the task that created the files in the build if Utils.is_win32 and len(tgt) > 259 and not tgt.startswith('\\\\?\\'): tgt = '\\\\?\\' + tgt shutil.copy2(src, tgt) os.chmod(tgt, kw.get('chmod', Utils.O644)) def do_install(self, src, tgt, **kw): """ Copy a file from src to tgt with given file permissions. The actual copy is not performed if the source and target file have the same size and the same timestamps. When the copy occurs, the file is first removed and then copied (prevent stale inodes). This method is overridden in :py:meth:`waflib.Build.UninstallContext.do_install` to remove the file. :param src: file name as absolute path :type src: string :param tgt: file destination, as absolute path :type tgt: string :param chmod: installation mode :type chmod: int """ d, _ = os.path.split(tgt) if not d: raise Errors.WafError('Invalid installation given %r->%r' % (src, tgt)) Utils.check_dir(d) srclbl = src.replace(self.srcnode.abspath() + os.sep, '') if not Options.options.force: # check if the file is already there to avoid a copy try: st1 = os.stat(tgt) st2 = os.stat(src) except OSError: pass else: # same size and identical timestamps -> make no copy if st1.st_mtime + 2 >= st2.st_mtime and st1.st_size == st2.st_size: if not self.progress_bar: Logs.info('- install %s (from %s)' % (tgt, srclbl)) return False if not self.progress_bar: Logs.info('+ install %s (from %s)' % (tgt, srclbl)) # Give best attempt at making destination overwritable, # like the 'install' utility used by 'make install' does. try: os.chmod(tgt, Utils.O644 | stat.S_IMODE(os.stat(tgt).st_mode)) except EnvironmentError: pass # following is for shared libs and stale inodes (-_-) try: os.remove(tgt) except OSError: pass try: self.copy_fun(src, tgt, **kw) except IOError: try: os.stat(src) except EnvironmentError: Logs.error('File %r does not exist' % src) raise Errors.WafError('Could not install the file %r' % tgt) def do_link(self, src, tgt, **kw): """ Create a symlink from tgt to src. This method is overridden in :py:meth:`waflib.Build.UninstallContext.do_link` to remove the symlink. :param src: file name as absolute path :type src: string :param tgt: file destination, as absolute path :type tgt: string """ d, _ = os.path.split(tgt) Utils.check_dir(d) link = False if not os.path.islink(tgt): link = True elif os.readlink(tgt) != src: link = True if link: try: os.remove(tgt) except OSError: pass if not self.progress_bar: Logs.info('+ symlink %s (to %s)' % (tgt, src)) os.symlink(src, tgt) else: if not self.progress_bar: Logs.info('- symlink %s (to %s)' % (tgt, src)) def run_task_now(self, tsk, postpone): """ This method is called by :py:meth:`waflib.Build.InstallContext.install_files`, :py:meth:`waflib.Build.InstallContext.install_as` and :py:meth:`waflib.Build.InstallContext.symlink_as` immediately after the installation task is created. Its role is to force the immediate execution if necessary, that is when ``postpone=False`` was given. """ tsk.post() if not postpone: if tsk.runnable_status() == Task.ASK_LATER: raise self.WafError('cannot post the task %r' % tsk) tsk.run() tsk.hasrun = True def install_files(self, dest, files, env=None, chmod=Utils.O644, relative_trick=False, cwd=None, add=True, postpone=True, task=None): """ Create a task to install files on the system:: def build(bld): bld.install_files('${DATADIR}', self.path.find_resource('wscript')) :param dest: absolute path of the destination directory :type dest: string :param files: input files :type files: list of strings or list of nodes :param env: configuration set for performing substitutions in dest :type env: Configuration set :param relative_trick: preserve the folder hierarchy when installing whole folders :type relative_trick: bool :param cwd: parent node for searching srcfile, when srcfile is not a :py:class:`waflib.Node.Node` :type cwd: :py:class:`waflib.Node.Node` :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started :type add: bool :param postpone: execute the task immediately to perform the installation :type postpone: bool """ assert(dest) tsk = inst(env=env or self.env) tsk.bld = self tsk.path = cwd or self.path tsk.chmod = chmod tsk.task = task if isinstance(files, waflib.Node.Node): tsk.source = [files] else: tsk.source = Utils.to_list(files) tsk.dest = dest tsk.exec_task = tsk.exec_install_files tsk.relative_trick = relative_trick if add: self.add_to_group(tsk) self.run_task_now(tsk, postpone) return tsk def install_as(self, dest, srcfile, env=None, chmod=Utils.O644, cwd=None, add=True, postpone=True, task=None): """ Create a task to install a file on the system with a different name:: def build(bld): bld.install_as('${PREFIX}/bin', 'myapp', chmod=Utils.O755) :param dest: absolute path of the destination file :type dest: string :param srcfile: input file :type srcfile: string or node :param cwd: parent node for searching srcfile, when srcfile is not a :py:class:`waflib.Node.Node` :type cwd: :py:class:`waflib.Node.Node` :param env: configuration set for performing substitutions in dest :type env: Configuration set :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started :type add: bool :param postpone: execute the task immediately to perform the installation :type postpone: bool """ assert(dest) tsk = inst(env=env or self.env) tsk.bld = self tsk.path = cwd or self.path tsk.chmod = chmod tsk.source = [srcfile] tsk.task = task tsk.dest = dest tsk.exec_task = tsk.exec_install_as if add: self.add_to_group(tsk) self.run_task_now(tsk, postpone) return tsk def symlink_as(self, dest, src, env=None, cwd=None, add=True, postpone=True, relative_trick=False, task=None): """ Create a task to install a symlink:: def build(bld): bld.symlink_as('${PREFIX}/lib/libfoo.so', 'libfoo.so.1.2.3') :param dest: absolute path of the symlink :type dest: string :param src: absolute or relative path of the link :type src: string :param env: configuration set for performing substitutions in dest :type env: Configuration set :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started :type add: bool :param postpone: execute the task immediately to perform the installation :type postpone: bool :param relative_trick: make the symlink relative (default: ``False``) :type relative_trick: bool """ if Utils.is_win32: # symlinks *cannot* work on that platform # TODO waf 1.9 - replace by install_as return assert(dest) tsk = inst(env=env or self.env) tsk.bld = self tsk.dest = dest tsk.path = cwd or self.path tsk.source = [] tsk.task = task tsk.link = src tsk.relative_trick = relative_trick tsk.exec_task = tsk.exec_symlink_as if add: self.add_to_group(tsk) self.run_task_now(tsk, postpone) return tsk class UninstallContext(InstallContext): '''removes the targets installed''' cmd = 'uninstall' def __init__(self, **kw): super(UninstallContext, self).__init__(**kw) self.is_install = UNINSTALL def rm_empty_dirs(self, tgt): while tgt: tgt = os.path.dirname(tgt) try: os.rmdir(tgt) except OSError: break def do_install(self, src, tgt, **kw): """See :py:meth:`waflib.Build.InstallContext.do_install`""" if not self.progress_bar: Logs.info('- remove %s' % tgt) self.uninstall.append(tgt) try: os.remove(tgt) except OSError as e: if e.errno != errno.ENOENT: if not getattr(self, 'uninstall_error', None): self.uninstall_error = True Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') if Logs.verbose > 1: Logs.warn('Could not remove %s (error code %r)' % (e.filename, e.errno)) self.rm_empty_dirs(tgt) def do_link(self, src, tgt, **kw): """See :py:meth:`waflib.Build.InstallContext.do_link`""" try: if not self.progress_bar: Logs.info('- remove %s' % tgt) os.remove(tgt) except OSError: pass self.rm_empty_dirs(tgt) def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ try: # do not execute any tasks def runnable_status(self): return Task.SKIP_ME setattr(Task.Task, 'runnable_status_back', Task.Task.runnable_status) setattr(Task.Task, 'runnable_status', runnable_status) super(UninstallContext, self).execute() finally: setattr(Task.Task, 'runnable_status', Task.Task.runnable_status_back) class CleanContext(BuildContext): '''cleans the project''' cmd = 'clean' def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) try: self.clean() finally: self.store() def clean(self): """Remove files from the build directory if possible, and reset the caches""" Logs.debug('build: clean called') if self.bldnode != self.srcnode: # would lead to a disaster if top == out lst=[] for e in self.all_envs.values(): lst.extend(self.root.find_or_declare(f) for f in e[CFG_FILES]) for n in self.bldnode.ant_glob('**/*', excl='.lock* *conf_check_*/** config.log c4che/*', quiet=True): if n in lst: continue n.delete() self.root.children = {} for v in 'node_deps task_sigs raw_deps'.split(): setattr(self, v, {}) class ListContext(BuildContext): '''lists the targets to execute''' cmd = 'list' def execute(self): """ See :py:func:`waflib.Context.Context.execute`. """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) self.pre_build() # display the time elapsed in the progress bar self.timer = Utils.Timer() for g in self.groups: for tg in g: try: f = tg.post except AttributeError: pass else: f() try: # force the cache initialization self.get_tgen_by_name('') except Exception: pass lst = list(self.task_gen_cache_names.keys()) lst.sort() for k in lst: Logs.pprint('GREEN', k) class StepContext(BuildContext): '''executes tasks in a step-by-step fashion, for debugging''' cmd = 'step' def __init__(self, **kw): super(StepContext, self).__init__(**kw) self.files = Options.options.files def compile(self): """ Compile the tasks matching the input/output files given (regular expression matching). Derived from :py:meth:`waflib.Build.BuildContext.compile`:: $ waf step --files=foo.c,bar.c,in:truc.c,out:bar.o $ waf step --files=in:foo.cpp.1.o # link task only """ if not self.files: Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"') BuildContext.compile(self) return targets = None if self.targets and self.targets != '*': targets = self.targets.split(',') for g in self.groups: for tg in g: if targets and tg.name not in targets: continue try: f = tg.post except AttributeError: pass else: f() for pat in self.files.split(','): matcher = self.get_matcher(pat) for tg in g: if isinstance(tg, Task.TaskBase): lst = [tg] else: lst = tg.tasks for tsk in lst: do_exec = False for node in getattr(tsk, 'inputs', []): if matcher(node, output=False): do_exec = True break for node in getattr(tsk, 'outputs', []): if matcher(node, output=True): do_exec = True break if do_exec: ret = tsk.run() Logs.info('%s -> exit %r' % (str(tsk), ret)) def get_matcher(self, pat): # this returns a function inn = True out = True if pat.startswith('in:'): out = False pat = pat.replace('in:', '') elif pat.startswith('out:'): inn = False pat = pat.replace('out:', '') anode = self.root.find_node(pat) pattern = None if not anode: if not pat.startswith('^'): pat = '^.+?%s' % pat if not pat.endswith('$'): pat = '%s$' % pat pattern = re.compile(pat) def match(node, output): if output == True and not out: return False if output == False and not inn: return False if anode: return anode == node else: return pattern.match(node.abspath()) return match 1.9.12~dfsg/waflib/extras/0000755000000000000000000000000013214314510014112 5ustar rootroot1.9.12~dfsg/waflib/extras/xcode6.py0000644000000000000000000005320613214314510015662 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 # XCode 3/XCode 4 generator for Waf # Based on work by Nicolas Mercier 2011 # Extended by Simon Warg 2015, https://github.com/mimon # XCode project file format based on http://www.monobjc.net/xcode-project-file-format.html """ Usage: See also demos/xcode6/ folder def options(opt): opt.load('xcode6') def configure(cnf): # # For example cnf.env.SDKROOT = 'macosx10.9' # Use cnf.PROJ_CONFIGURATION to completely set/override # global project settings # cnf.env.PROJ_CONFIGURATION = { # 'Debug': { # 'SDKROOT': 'macosx10.9' # } # 'MyCustomReleaseConfig': { # 'SDKROOT': 'macosx10.10' # } # } # In the end of configure() do cnf.load('xcode6') def build(bld): # Make a Framework target bld.framework( source_files={ 'Include': bld.path.ant_glob('include/MyLib/*.h'), 'Source': bld.path.ant_glob('src/MyLib/*.cpp') }, includes='include', export_headers=bld.path.ant_glob('include/MyLib/*.h'), target='MyLib', ) # You can also make bld.dylib, bld.app, bld.stlib ... $ waf configure xcode6 """ # TODO: support iOS projects from waflib import Context, TaskGen, Build, Utils, ConfigSet, Configure, Errors from waflib.Build import BuildContext import os, sys, random, time HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' MAP_EXT = { '': "folder", '.h' : "sourcecode.c.h", '.hh': "sourcecode.cpp.h", '.inl': "sourcecode.cpp.h", '.hpp': "sourcecode.cpp.h", '.c': "sourcecode.c.c", '.m': "sourcecode.c.objc", '.mm': "sourcecode.cpp.objcpp", '.cc': "sourcecode.cpp.cpp", '.cpp': "sourcecode.cpp.cpp", '.C': "sourcecode.cpp.cpp", '.cxx': "sourcecode.cpp.cpp", '.c++': "sourcecode.cpp.cpp", '.l': "sourcecode.lex", # luthor '.ll': "sourcecode.lex", '.y': "sourcecode.yacc", '.yy': "sourcecode.yacc", '.plist': "text.plist.xml", ".nib": "wrapper.nib", ".xib": "text.xib", } # Used in PBXNativeTarget elements PRODUCT_TYPE_APPLICATION = 'com.apple.product-type.application' PRODUCT_TYPE_FRAMEWORK = 'com.apple.product-type.framework' PRODUCT_TYPE_EXECUTABLE = 'com.apple.product-type.tool' PRODUCT_TYPE_LIB_STATIC = 'com.apple.product-type.library.static' PRODUCT_TYPE_LIB_DYNAMIC = 'com.apple.product-type.library.dynamic' PRODUCT_TYPE_EXTENSION = 'com.apple.product-type.kernel-extension' PRODUCT_TYPE_IOKIT = 'com.apple.product-type.kernel-extension.iokit' # Used in PBXFileReference elements FILE_TYPE_APPLICATION = 'wrapper.cfbundle' FILE_TYPE_FRAMEWORK = 'wrapper.framework' FILE_TYPE_LIB_DYNAMIC = 'compiled.mach-o.dylib' FILE_TYPE_LIB_STATIC = 'archive.ar' FILE_TYPE_EXECUTABLE = 'compiled.mach-o.executable' # Tuple packs of the above TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') TARGET_TYPE_DYNAMIC_LIB = (PRODUCT_TYPE_LIB_DYNAMIC, FILE_TYPE_LIB_DYNAMIC, '.dylib') TARGET_TYPE_STATIC_LIB = (PRODUCT_TYPE_LIB_STATIC, FILE_TYPE_LIB_STATIC, '.a') TARGET_TYPE_EXECUTABLE = (PRODUCT_TYPE_EXECUTABLE, FILE_TYPE_EXECUTABLE, '') # Maps target type string to its data TARGET_TYPES = { 'framework': TARGET_TYPE_FRAMEWORK, 'app': TARGET_TYPE_APPLICATION, 'dylib': TARGET_TYPE_DYNAMIC_LIB, 'stlib': TARGET_TYPE_STATIC_LIB, 'exe' :TARGET_TYPE_EXECUTABLE, } """ Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' which is a dictionary of configuration name and buildsettings pair. E.g.: env.PROJ_CONFIGURATION = { 'Debug': { 'ARCHS': 'x86', ... } 'Release': { 'ARCHS' x86_64' ... } } The user can define a completely customized dictionary in configure() stage. Otherwise a default Debug/Release will be created based on env variable """ def configure(self): if not self.env.PROJ_CONFIGURATION: self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") # Check for any added config files added by the tool 'c_config'. if 'cfg_files' in self.env: self.env.INCLUDES = Utils.to_list(self.env.INCLUDES) + [os.path.abspath(os.path.dirname(f)) for f in self.env.cfg_files] # Create default project configuration? if 'PROJ_CONFIGURATION' not in self.env: self.env.PROJ_CONFIGURATION = { "Debug": self.env.get_merged_dict(), "Release": self.env.get_merged_dict(), } # Some build settings are required to be present by XCode. We will supply default values # if user hasn't defined any. defaults_required = [('PRODUCT_NAME', '$(TARGET_NAME)')] for cfgname,settings in self.env.PROJ_CONFIGURATION.iteritems(): for default_var, default_val in defaults_required: if default_var not in settings: settings[default_var] = default_val # Error check customization if not isinstance(self.env.PROJ_CONFIGURATION, dict): raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") part1 = 0 part2 = 10000 part3 = 0 id = 562000999 def newid(): global id id = id + 1 return "%04X%04X%04X%012d" % (0, 10000, 0, id) class XCodeNode: def __init__(self): self._id = newid() self._been_written = False def tostring(self, value): if isinstance(value, dict): result = "{\n" for k,v in value.items(): result = result + "\t\t\t%s = %s;\n" % (k, self.tostring(v)) result = result + "\t\t}" return result elif isinstance(value, str): return "\"%s\"" % value elif isinstance(value, list): result = "(\n" for i in value: result = result + "\t\t\t%s,\n" % self.tostring(i) result = result + "\t\t)" return result elif isinstance(value, XCodeNode): return value._id else: return str(value) def write_recursive(self, value, file): if isinstance(value, dict): for k,v in value.items(): self.write_recursive(v, file) elif isinstance(value, list): for i in value: self.write_recursive(i, file) elif isinstance(value, XCodeNode): value.write(file) def write(self, file): if not self._been_written: self._been_written = True for attribute,value in self.__dict__.items(): if attribute[0] != '_': self.write_recursive(value, file) w = file.write w("\t%s = {\n" % self._id) w("\t\tisa = %s;\n" % self.__class__.__name__) for attribute,value in self.__dict__.items(): if attribute[0] != '_': w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) w("\t};\n\n") # Configurations class XCBuildConfiguration(XCodeNode): def __init__(self, name, settings = {}, env=None): XCodeNode.__init__(self) self.baseConfigurationReference = "" self.buildSettings = settings self.name = name if env and env.ARCH: settings['ARCHS'] = " ".join(env.ARCH) class XCConfigurationList(XCodeNode): def __init__(self, configlst): """ :param configlst: list of XCConfigurationList """ XCodeNode.__init__(self) self.buildConfigurations = configlst self.defaultConfigurationIsVisible = 0 self.defaultConfigurationName = configlst and configlst[0].name or "" # Group/Files class PBXFileReference(XCodeNode): def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): XCodeNode.__init__(self) self.fileEncoding = 4 if not filetype: _, ext = os.path.splitext(name) filetype = MAP_EXT.get(ext, 'text') self.lastKnownFileType = filetype self.name = name self.path = path self.sourceTree = sourcetree def __hash__(self): return (self.path+self.name).__hash__() def __eq__(self, other): return (self.path, self.name) == (other.path, other.name) class PBXBuildFile(XCodeNode): """ This element indicate a file reference that is used in a PBXBuildPhase (either as an include or resource). """ def __init__(self, fileRef, settings={}): XCodeNode.__init__(self) # fileRef is a reference to a PBXFileReference object self.fileRef = fileRef # A map of key/value pairs for additionnal settings. self.settings = settings def __hash__(self): return (self.fileRef).__hash__() def __eq__(self, other): return self.fileRef == other.fileRef class PBXGroup(XCodeNode): def __init__(self, name, sourcetree = ""): XCodeNode.__init__(self) self.children = [] self.name = name self.sourceTree = sourcetree def add(self, sources): """ sources param should be a list of PBXFileReference objects """ self.children.extend(sources) class PBXContainerItemProxy(XCodeNode): """ This is the element for to decorate a target item. """ def __init__(self, containerPortal, remoteGlobalIDString, remoteInfo='', proxyType=1): XCodeNode.__init__(self) self.containerPortal = containerPortal # PBXProject self.remoteGlobalIDString = remoteGlobalIDString # PBXNativeTarget self.remoteInfo = remoteInfo # Target name self.proxyType = proxyType class PBXTargetDependency(XCodeNode): """ This is the element for referencing other target through content proxies. """ def __init__(self, native_target, proxy): XCodeNode.__init__(self) self.target = native_target self.targetProxy = proxy class PBXFrameworksBuildPhase(XCodeNode): """ This is the element for the framework link build phase, i.e. linking to frameworks """ def __init__(self, pbxbuildfiles): XCodeNode.__init__(self) self.buildActionMask = 2147483647 self.runOnlyForDeploymentPostprocessing = 0 self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) class PBXHeadersBuildPhase(XCodeNode): """ This is the element for adding header files to be packaged into the .framework """ def __init__(self, pbxbuildfiles): XCodeNode.__init__(self) self.buildActionMask = 2147483647 self.runOnlyForDeploymentPostprocessing = 0 self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) class PBXCopyFilesBuildPhase(XCodeNode): """ Represents the PBXCopyFilesBuildPhase section. PBXBuildFile can be added to this node to copy files after build is done. """ def __init__(self, pbxbuildfiles, dstpath, dstSubpathSpec=0, *args, **kwargs): XCodeNode.__init__(self) self.files = pbxbuildfiles self.dstPath = dstpath self.dstSubfolderSpec = dstSubpathSpec class PBXSourcesBuildPhase(XCodeNode): """ Represents the 'Compile Sources' build phase in a Xcode target """ def __init__(self, buildfiles): XCodeNode.__init__(self) self.files = buildfiles # List of PBXBuildFile objects class PBXLegacyTarget(XCodeNode): def __init__(self, action, target=''): XCodeNode.__init__(self) self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})]) if not target: self.buildArgumentsString = "%s %s" % (sys.argv[0], action) else: self.buildArgumentsString = "%s %s --targets=%s" % (sys.argv[0], action, target) self.buildPhases = [] self.buildToolPath = sys.executable self.buildWorkingDirectory = "" self.dependencies = [] self.name = target or action self.productName = target or action self.passBuildSettingsInEnvironment = 0 class PBXShellScriptBuildPhase(XCodeNode): def __init__(self, action, target): XCodeNode.__init__(self) self.buildActionMask = 2147483647 self.files = [] self.inputPaths = [] self.outputPaths = [] self.runOnlyForDeploymentPostProcessing = 0 self.shellPath = "/bin/sh" self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): """ Represents a target in XCode, e.g. App, DyLib, Framework etc. """ def __init__(self, target, node, target_type=TARGET_TYPE_APPLICATION, configlist=[], buildphases=[]): XCodeNode.__init__(self) product_type = target_type[0] file_type = target_type[1] self.buildConfigurationList = XCConfigurationList(configlist) self.buildPhases = buildphases self.buildRules = [] self.dependencies = [] self.name = target self.productName = target self.productType = product_type # See TARGET_TYPE_ tuples constants self.productReference = PBXFileReference(node.name, node.abspath(), file_type, '') def add_configuration(self, cf): """ :type cf: XCBuildConfiguration """ self.buildConfigurationList.buildConfigurations.append(cf) def add_build_phase(self, phase): # Some build phase types may appear only once. If a phase type already exists, then merge them. if ( (phase.__class__ == PBXFrameworksBuildPhase) or (phase.__class__ == PBXSourcesBuildPhase) ): for b in self.buildPhases: if b.__class__ == phase.__class__: b.files.extend(phase.files) return self.buildPhases.append(phase) def add_dependency(self, depnd): self.dependencies.append(depnd) # Root project object class PBXProject(XCodeNode): def __init__(self, name, version, env): XCodeNode.__init__(self) if not isinstance(env.PROJ_CONFIGURATION, dict): raise Errors.WafError("Error: env.PROJ_CONFIGURATION must be a dictionary. This is done for you if you do not define one yourself. However, did you load the xcode module at the end of your wscript configure() ?") # Retreive project configuration configurations = [] for config_name, settings in env.PROJ_CONFIGURATION.items(): cf = XCBuildConfiguration(config_name, settings) configurations.append(cf) self.buildConfigurationList = XCConfigurationList(configurations) self.compatibilityVersion = version[0] self.hasScannedForEncodings = 1; self.mainGroup = PBXGroup(name) self.projectRoot = "" self.projectDirPath = "" self.targets = [] self._objectVersion = version[1] def create_target_dependency(self, target, name): """ : param target : PXBNativeTarget """ proxy = PBXContainerItemProxy(self, target, name) dependecy = PBXTargetDependency(target, proxy) return dependecy def write(self, file): # Make sure this is written only once if self._been_written: return w = file.write w("// !$*UTF8*$!\n") w("{\n") w("\tarchiveVersion = 1;\n") w("\tclasses = {\n") w("\t};\n") w("\tobjectVersion = %d;\n" % self._objectVersion) w("\tobjects = {\n\n") XCodeNode.write(self, file) w("\t};\n") w("\trootObject = %s;\n" % self._id) w("}\n") def add_target(self, target): self.targets.append(target) def get_target(self, name): """ Get a reference to PBXNativeTarget if it exists """ for t in self.targets: if t.name == name: return t return None class xcode(Build.BuildContext): cmd = 'xcode6' fun = 'build' file_refs = dict() build_files = dict() def as_nodes(self, files): """ Returns a list of waflib.Nodes from a list of string of file paths """ nodes = [] for x in files: if not isinstance(x, str): d = x else: d = self.srcnode.find_node(x) nodes.append(d) return nodes def create_group(self, name, files): """ Returns a new PBXGroup containing the files (paths) passed in the files arg :type files: string """ group = PBXGroup(name) """ Do not use unique file reference here, since XCode seem to allow only one file reference to be referenced by a group. """ files = [(PBXFileReference(d.name, d.abspath())) for d in self.as_nodes(files)] group.add(files) return group def unique_filereference(self, fileref): """ Returns a unique fileref, possibly an existing one if the paths are the same. Use this after you've constructed a PBXFileReference to make sure there is only one PBXFileReference for the same file in the same project. """ if fileref not in self.file_refs: self.file_refs[fileref] = fileref return self.file_refs[fileref] def unique_buildfile(self, buildfile): """ Returns a unique buildfile, possibly an existing one. Use this after you've constructed a PBXBuildFile to make sure there is only one PBXBuildFile for the same file in the same project. """ if buildfile not in self.build_files: self.build_files[buildfile] = buildfile return self.build_files[buildfile] def execute(self): """ Entry point """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) p = PBXProject(appname, ('Xcode 3.2', 46), self.env) # If we don't create a Products group, then # XCode will create one, which entails that # we'll start to see duplicate files in the UI # for some reason. products_group = PBXGroup('Products') p.mainGroup.children.append(products_group) for g in self.groups: for tg in g: if not isinstance(tg, TaskGen.task_gen): continue tg.post() target_group = PBXGroup(tg.name) p.mainGroup.children.append(target_group) # Determine what type to build - framework, app bundle etc. target_type = getattr(tg, 'target_type', 'app') if target_type not in TARGET_TYPES: raise Errors.WafError("Target type '%s' does not exists. Available options are '%s'. In target '%s'" % (target_type, "', '".join(TARGET_TYPES.keys()), tg.name)) else: target_type = TARGET_TYPES[target_type] file_ext = target_type[2] # Create the output node target_node = tg.path.find_or_declare(tg.name+file_ext) target = PBXNativeTarget(tg.name, target_node, target_type, [], []) products_group.children.append(target.productReference) if hasattr(tg, 'source_files'): # Create list of PBXFileReferences sources = [] if isinstance(tg.source_files, dict): for grpname,files in tg.source_files.items(): group = self.create_group(grpname, files) target_group.children.append(group) sources.extend(group.children) elif isinstance(tg.source_files, list): group = self.create_group("Source", tg.source_files) target_group.children.append(group) sources.extend(group.children) else: self.to_log("Argument 'source_files' passed to target '%s' was not a dictionary. Hence, some source files may not be included. Please provide a dictionary of source files, with group name as key and list of source files as value.\n" % tg.name) supported_extensions = ['.c', '.cpp', '.m', '.mm'] sources = filter(lambda fileref: os.path.splitext(fileref.path)[1] in supported_extensions, sources) buildfiles = [self.unique_buildfile(PBXBuildFile(fileref)) for fileref in sources] target.add_build_phase(PBXSourcesBuildPhase(buildfiles)) # Create build settings which can override the project settings. Defaults to none if user # did not pass argument. However, this will be filled up further below with target specfic # search paths, libs to link etc. settings = getattr(tg, 'settings', {}) # Check if any framework to link against is some other target we've made libs = getattr(tg, 'tmp_use_seen', []) for lib in libs: use_target = p.get_target(lib) if use_target: # Create an XCode dependency so that XCode knows to build the other target before this target target.add_dependency(p.create_target_dependency(use_target, use_target.name)) target.add_build_phase(PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)])) if lib in tg.env.LIB: tg.env.LIB = list(filter(lambda x: x != lib, tg.env.LIB)) # If 'export_headers' is present, add files to the Headers build phase in xcode. # These are files that'll get packed into the Framework for instance. exp_hdrs = getattr(tg, 'export_headers', []) hdrs = self.as_nodes(Utils.to_list(exp_hdrs)) files = [self.unique_filereference(PBXFileReference(n.name, n.abspath())) for n in hdrs] target.add_build_phase(PBXHeadersBuildPhase([PBXBuildFile(f, {'ATTRIBUTES': ('Public',)}) for f in files])) # Install path installpaths = Utils.to_list(getattr(tg, 'install', [])) prodbuildfile = PBXBuildFile(target.productReference) for instpath in installpaths: target.add_build_phase(PBXCopyFilesBuildPhase([prodbuildfile], instpath)) # Merge frameworks and libs into one list, and prefix the frameworks ld_flags = ['-framework %s' % lib.split('.framework')[0] for lib in Utils.to_list(tg.env.FRAMEWORK)] ld_flags.extend(Utils.to_list(tg.env.STLIB) + Utils.to_list(tg.env.LIB)) # Override target specfic build settings bldsettings = { 'HEADER_SEARCH_PATHS': ['$(inherited)'] + tg.env['INCPATHS'], 'LIBRARY_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(tg.env.LIBPATH) + Utils.to_list(tg.env.STLIBPATH), 'FRAMEWORK_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(tg.env.FRAMEWORKPATH), 'OTHER_LDFLAGS': r'\n'.join(ld_flags) } # The keys represents different build configuration, e.g. Debug, Release and so on.. # Insert our generated build settings to all configuration names keys = set(settings.keys() + self.env.PROJ_CONFIGURATION.keys()) for k in keys: if k in settings: settings[k].update(bldsettings) else: settings[k] = bldsettings for k,v in settings.items(): target.add_configuration(XCBuildConfiguration(k, v)) p.add_target(target) node = self.bldnode.make_node('%s.xcodeproj' % appname) node.mkdir() node = node.make_node('project.pbxproj') p.write(open(node.abspath(), 'w')) def build_target(self, tgtype, *k, **kw): """ Provide user-friendly methods to build different target types E.g. bld.framework(source='..', ...) to build a Framework target. E.g. bld.dylib(source='..', ...) to build a Dynamic library target. etc... """ self.load('ccroot') kw['features'] = 'cxx cxxprogram' kw['target_type'] = tgtype return self(*k, **kw) def app(self, *k, **kw): return self.build_target('app', *k, **kw) def framework(self, *k, **kw): return self.build_target('framework', *k, **kw) def dylib(self, *k, **kw): return self.build_target('dylib', *k, **kw) def stlib(self, *k, **kw): return self.build_target('stlib', *k, **kw) def exe(self, *k, **kw): return self.build_target('exe', *k, **kw) 1.9.12~dfsg/waflib/extras/batched_cc.py0000644000000000000000000001063313214314510016526 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2006-2015 (ita) """ Build as batches. Instead of compiling object files one by one, c/c++ compilers are often able to compile at once: cc -c ../file1.c ../file2.c ../file3.c Files are output on the directory where the compiler is called, and dependencies are more difficult to track (do not run the command on all source files if only one file changes) As such, we do as if the files were compiled one by one, but no command is actually run: replace each cc/cpp Task by a TaskSlave. A new task called TaskMaster collects the signatures from each slave and finds out the command-line to run. Just import this module in the configuration (no other change required). This is provided as an example, for performance unity builds are recommended (fewer tasks and fewer jobs to execute). See waflib/extras/unity.py. """ from waflib import Task, Utils from waflib.TaskGen import extension, feature, after_method from waflib.Tools import c, cxx MAX_BATCH = 50 c_str = '${CC} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED}' c_fun, _ = Task.compile_fun_noshell(c_str) cxx_str = '${CXX} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED}' cxx_fun, _ = Task.compile_fun_noshell(cxx_str) count = 70000 class batch_task(Task.Task): color = 'PINK' after = ['c', 'cxx'] before = ['cprogram', 'cshlib', 'cstlib', 'cxxprogram', 'cxxshlib', 'cxxstlib'] def uid(self): m = Utils.md5() m.update(Task.Task.uid(self)) m.update(str(self.generator.idx).encode()) return m.digest() def __str__(self): return 'Batch compilation for %d slaves' % len(self.slaves) def __init__(self, *k, **kw): Task.Task.__init__(self, *k, **kw) self.slaves = [] self.inputs = [] self.hasrun = 0 global count count += 1 self.idx = count def add_slave(self, slave): self.slaves.append(slave) self.set_run_after(slave) def runnable_status(self): for t in self.run_after: if not t.hasrun: return Task.ASK_LATER for t in self.slaves: #if t.executed: if t.hasrun != Task.SKIPPED: return Task.RUN_ME return Task.SKIP_ME def run(self): self.outputs = [] srclst = [] slaves = [] for t in self.slaves: if t.hasrun != Task.SKIPPED: slaves.append(t) srclst.append(t.inputs[0].abspath()) self.env.SRCLST = srclst self.cwd = slaves[0].outputs[0].parent.abspath() if self.slaves[0].__class__.__name__ == 'c': ret = c_fun(self) else: ret = cxx_fun(self) if ret: return ret for t in slaves: t.old_post_run() def hook(cls_type): def n_hook(self, node): ext = '.obj' if self.env.CC_NAME == 'msvc' else '.o' name = node.name k = name.rfind('.') if k >= 0: basename = name[:k] + ext else: basename = name + ext outdir = node.parent.get_bld().make_node('%d' % self.idx) outdir.mkdir() out = outdir.find_or_declare(basename) task = self.create_task(cls_type, node, out) try: self.compiled_tasks.append(task) except AttributeError: self.compiled_tasks = [task] if not getattr(self, 'masters', None): self.masters = {} self.allmasters = [] def fix_path(tsk): if self.env.CC_NAME == 'msvc': tsk.env.append_unique('CXX_TGT_F_BATCHED', '/Fo%s\\' % outdir.abspath()) if not node.parent in self.masters: m = self.masters[node.parent] = self.master = self.create_task('batch') fix_path(m) self.allmasters.append(m) else: m = self.masters[node.parent] if len(m.slaves) > MAX_BATCH: m = self.masters[node.parent] = self.master = self.create_task('batch') fix_path(m) self.allmasters.append(m) m.add_slave(task) return task return n_hook extension('.c')(hook('c')) extension('.cpp','.cc','.cxx','.C','.c++')(hook('cxx')) @feature('cprogram', 'cshlib', 'cstaticlib', 'cxxprogram', 'cxxshlib', 'cxxstlib') @after_method('apply_link') def link_after_masters(self): if getattr(self, 'allmasters', None): for m in self.allmasters: self.link_task.set_run_after(m) # Modify the c and cxx task classes - in theory it would be best to # create subclasses and to re-map the c/c++ extensions for x in ('c', 'cxx'): t = Task.classes[x] def run(self): pass def post_run(self): pass setattr(t, 'oldrun', getattr(t, 'run', None)) setattr(t, 'run', run) setattr(t, 'old_post_run', t.post_run) setattr(t, 'post_run', post_run) 1.9.12~dfsg/waflib/extras/build_logs.py0000644000000000000000000000542713214314510016617 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2013 (ita) """ A system for recording all outputs to a log file. Just add the following to your wscript file:: def init(ctx): ctx.load('build_logs') """ import atexit, sys, time, os, shutil, threading from waflib import ansiterm, Logs, Context # adding the logs under the build/ directory will clash with the clean/ command try: up = os.path.dirname(Context.g_module.__file__) except AttributeError: up = '.' LOGFILE = os.path.join(up, 'logs', '%s.log' % time.strftime('%Y_%m_%d_%H_%M')) wlock = threading.Lock() class log_to_file(object): def __init__(self, stream, fileobj, filename): self.stream = stream self.encoding = self.stream.encoding self.fileobj = fileobj self.filename = filename self.is_valid = True def replace_colors(self, data): for x in Logs.colors_lst.values(): if isinstance(x, str): data = data.replace(x, '') return data def write(self, data): try: wlock.acquire() self.stream.write(data) self.stream.flush() if self.is_valid: self.fileobj.write(self.replace_colors(data)) finally: wlock.release() def fileno(self): return self.stream.fileno() def flush(self): self.stream.flush() if self.is_valid: self.fileobj.flush() def isatty(self): return self.stream.isatty() def init(ctx): global LOGFILE filename = os.path.abspath(LOGFILE) try: os.makedirs(os.path.dirname(os.path.abspath(filename))) except OSError: pass if hasattr(os, 'O_NOINHERIT'): fd = os.open(LOGFILE, os.O_CREAT | os.O_TRUNC | os.O_WRONLY | os.O_NOINHERIT) fileobj = os.fdopen(fd, 'w') else: fileobj = open(LOGFILE, 'w') old_stderr = sys.stderr # sys.stdout has already been replaced, so __stdout__ will be faster #sys.stdout = log_to_file(sys.stdout, fileobj, filename) #sys.stderr = log_to_file(sys.stderr, fileobj, filename) def wrap(stream): if stream.isatty(): return ansiterm.AnsiTerm(stream) return stream sys.stdout = log_to_file(wrap(sys.__stdout__), fileobj, filename) sys.stderr = log_to_file(wrap(sys.__stderr__), fileobj, filename) # now mess with the logging module... for x in Logs.log.handlers: try: stream = x.stream except AttributeError: pass else: if id(stream) == id(old_stderr): x.stream = sys.stderr def exit_cleanup(): try: fileobj = sys.stdout.fileobj except AttributeError: pass else: sys.stdout.is_valid = False sys.stderr.is_valid = False fileobj.close() filename = sys.stdout.filename Logs.info('Output logged to %r' % filename) # then copy the log file to "latest.log" if possible up = os.path.dirname(os.path.abspath(filename)) try: shutil.copy(filename, os.path.join(up, 'latest.log')) except OSError: # this may fail on windows due to processes spawned # pass atexit.register(exit_cleanup) 1.9.12~dfsg/waflib/extras/build_file_tracker.py0000644000000000000000000000173313214314510020301 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2015 """ Force files to depend on the timestamps of those located in the build directory. You may want to use this to force partial rebuilds, see playground/track_output_files/ for a working example. Note that there is a variety of ways to implement this, one may want use timestamps on source files too for example, or one may want to hash the files in the source directory only under certain conditions (md5_tstamp tool) or to hash the file in the build directory with its timestamp (similar to 'update_outputs') """ import os from waflib import Node, Utils def get_bld_sig(self): try: return self.cache_sig except AttributeError: pass if not self.is_bld() or self.ctx.bldnode is self.ctx.srcnode: self.sig = Utils.h_file(self.abspath()) self.cache_sig = ret = self.sig else: # add the self.cache_sig = ret = self.sig + str(os.stat(self.abspath()).st_mtime) return ret Node.Node.get_bld_sig = get_bld_sig 1.9.12~dfsg/waflib/extras/c_nec.py0000644000000000000000000000364213214314510015540 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de """ NEC SX Compiler for SX vector systems """ import re from waflib import Utils from waflib.Tools import ccroot,ar from waflib.Configure import conf from waflib.Tools import xlc # method xlc_common_flags from waflib.Tools.compiler_c import c_compiler c_compiler['linux'].append('c_nec') @conf def find_sxc(conf): cc = conf.find_program(['sxcc'], var='CC') conf.get_sxc_version(cc) conf.env.CC = cc conf.env.CC_NAME = 'sxcc' @conf def get_sxc_version(conf, fc): version_re = re.compile(r"C\+\+/SX\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search cmd = fc + ['-V'] p = Utils.subprocess.Popen(cmd, stdin=False, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=None) out, err = p.communicate() if out: match = version_re(out) else: match = version_re(err) if not match: conf.fatal('Could not determine the NEC C compiler version.') k = match.groupdict() conf.env['C_VERSION'] = (k['major'], k['minor']) @conf def sxc_common_flags(conf): v=conf.env v['CC_SRC_F']=[] v['CC_TGT_F']=['-c','-o'] if not v['LINK_CC']:v['LINK_CC']=v['CC'] v['CCLNK_SRC_F']=[] v['CCLNK_TGT_F']=['-o'] v['CPPPATH_ST']='-I%s' v['DEFINES_ST']='-D%s' v['LIB_ST']='-l%s' v['LIBPATH_ST']='-L%s' v['STLIB_ST']='-l%s' v['STLIBPATH_ST']='-L%s' v['RPATH_ST']='' v['SONAME_ST']=[] v['SHLIB_MARKER']=[] v['STLIB_MARKER']=[] v['LINKFLAGS_cprogram']=[''] v['cprogram_PATTERN']='%s' v['CFLAGS_cshlib']=['-fPIC'] v['LINKFLAGS_cshlib']=[''] v['cshlib_PATTERN']='lib%s.so' v['LINKFLAGS_cstlib']=[] v['cstlib_PATTERN']='lib%s.a' def configure(conf): conf.find_sxc() conf.find_program('sxar',VAR='AR') conf.sxc_common_flags() conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/extras/__init__.py0000644000000000000000000000010713214314510016221 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) 1.9.12~dfsg/waflib/extras/c_bgxlc.py0000644000000000000000000000130213214314510016061 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 # harald at klimachs.de """ IBM XL Compiler for Blue Gene """ from waflib.Tools import ccroot,ar from waflib.Configure import conf from waflib.Tools import xlc # method xlc_common_flags from waflib.Tools.compiler_c import c_compiler c_compiler['linux'].append('c_bgxlc') @conf def find_bgxlc(conf): cc = conf.find_program(['bgxlc_r','bgxlc'], var='CC') conf.get_xlc_version(cc) conf.env.CC = cc conf.env.CC_NAME = 'bgxlc' def configure(conf): conf.find_bgxlc() conf.find_ar() conf.xlc_common_flags() conf.env.LINKFLAGS_cshlib = ['-G','-Wl,-bexpfull'] conf.env.LINKFLAGS_cprogram = [] conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() 1.9.12~dfsg/waflib/extras/xcode.py0000644000000000000000000002031213214314510015564 0ustar rootroot#! /usr/bin/env python # encoding: utf-8 # XCode 3/XCode 4 generator for Waf # Nicolas Mercier 2011 """ Usage: def options(opt): opt.load('xcode') $ waf configure xcode """ # TODO: support iOS projects from waflib import Context, TaskGen, Build, Utils import os, sys HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' MAP_EXT = { '.h' : "sourcecode.c.h", '.hh': "sourcecode.cpp.h", '.inl': "sourcecode.cpp.h", '.hpp': "sourcecode.cpp.h", '.c': "sourcecode.c.c", '.m': "sourcecode.c.objc", '.mm': "sourcecode.cpp.objcpp", '.cc': "sourcecode.cpp.cpp", '.cpp': "sourcecode.cpp.cpp", '.C': "sourcecode.cpp.cpp", '.cxx': "sourcecode.cpp.cpp", '.c++': "sourcecode.cpp.cpp", '.l': "sourcecode.lex", # luthor '.ll': "sourcecode.lex", '.y': "sourcecode.yacc", '.yy': "sourcecode.yacc", '.plist': "text.plist.xml", ".nib": "wrapper.nib", ".xib": "text.xib", } part1 = 0 part2 = 10000 part3 = 0 id = 562000999 def newid(): global id id = id + 1 return "%04X%04X%04X%012d" % (0, 10000, 0, id) class XCodeNode: def __init__(self): self._id = newid() def tostring(self, value): if isinstance(value, dict): result = "{\n" for k,v in value.items(): result = result + "\t\t\t%s = %s;\n" % (k, self.tostring(v)) result = result + "\t\t}" return result elif isinstance(value, str): return "\"%s\"" % value elif isinstance(value, list): result = "(\n" for i in value: result = result + "\t\t\t%s,\n" % self.tostring(i) result = result + "\t\t)" return result elif isinstance(value, XCodeNode): return value._id else: return str(value) def write_recursive(self, value, file): if isinstance(value, dict): for k,v in value.items(): self.write_recursive(v, file) elif isinstance(value, list): for i in value: self.write_recursive(i, file) elif isinstance(value, XCodeNode): value.write(file) def write(self, file): for attribute,value in self.__dict__.items(): if attribute[0] != '_': self.write_recursive(value, file) w = file.write w("\t%s = {\n" % self._id) w("\t\tisa = %s;\n" % self.__class__.__name__) for attribute,value in self.__dict__.items(): if attribute[0] != '_': w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) w("\t};\n\n") # Configurations class XCBuildConfiguration(XCodeNode): def __init__(self, name, settings = {}, env=None): XCodeNode.__init__(self) self.baseConfigurationReference = "" self.buildSettings = settings self.name = name if env and env.ARCH: settings['ARCHS'] = " ".join(env.ARCH) class XCConfigurationList(XCodeNode): def __init__(self, settings): XCodeNode.__init__(self) self.buildConfigurations = settings self.defaultConfigurationIsVisible = 0 self.defaultConfigurationName = settings and settings[0].name or "" # Group/Files class PBXFileReference(XCodeNode): def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): XCodeNode.__init__(self) self.fileEncoding = 4 if not filetype: _, ext = os.path.splitext(name) filetype = MAP_EXT.get(ext, 'text') self.lastKnownFileType = filetype self.name = name self.path = path self.sourceTree = sourcetree class PBXGroup(XCodeNode): def __init__(self, name, sourcetree = ""): XCodeNode.__init__(self) self.children = [] self.name = name self.sourceTree = sourcetree def add(self, root, sources): folders = {} def folder(n): if not n.is_child_of(root): return self try: return folders[n] except KeyError: f = PBXGroup(n.name) p = folder(n.parent) folders[n] = f p.children.append(f) return f for s in sources: f = folder(s.parent) source = PBXFileReference(s.name, s.abspath()) f.children.append(source) # Targets class PBXLegacyTarget(XCodeNode): def __init__(self, action, target=''): XCodeNode.__init__(self) self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})]) if not target: self.buildArgumentsString = "%s %s" % (sys.argv[0], action) else: self.buildArgumentsString = "%s %s --targets=%s" % (sys.argv[0], action, target) self.buildPhases = [] self.buildToolPath = sys.executable self.buildWorkingDirectory = "" self.dependencies = [] self.name = target or action self.productName = target or action self.passBuildSettingsInEnvironment = 0 class PBXShellScriptBuildPhase(XCodeNode): def __init__(self, action, target): XCodeNode.__init__(self) self.buildActionMask = 2147483647 self.files = [] self.inputPaths = [] self.outputPaths = [] self.runOnlyForDeploymentPostProcessing = 0 self.shellPath = "/bin/sh" self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): def __init__(self, action, target, node, env): XCodeNode.__init__(self) conf = XCBuildConfiguration('waf', {'PRODUCT_NAME':target, 'CONFIGURATION_BUILD_DIR':node.parent.abspath()}, env) self.buildConfigurationList = XCConfigurationList([conf]) self.buildPhases = [PBXShellScriptBuildPhase(action, target)] self.buildRules = [] self.dependencies = [] self.name = target self.productName = target self.productType = "com.apple.product-type.application" self.productReference = PBXFileReference(target, node.abspath(), 'wrapper.application', 'BUILT_PRODUCTS_DIR') # Root project object class PBXProject(XCodeNode): def __init__(self, name, version): XCodeNode.__init__(self) self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})]) self.compatibilityVersion = version[0] self.hasScannedForEncodings = 1; self.mainGroup = PBXGroup(name) self.projectRoot = "" self.projectDirPath = "" self.targets = [] self._objectVersion = version[1] self._output = PBXGroup('out') self.mainGroup.children.append(self._output) def write(self, file): w = file.write w("// !$*UTF8*$!\n") w("{\n") w("\tarchiveVersion = 1;\n") w("\tclasses = {\n") w("\t};\n") w("\tobjectVersion = %d;\n" % self._objectVersion) w("\tobjects = {\n\n") XCodeNode.write(self, file) w("\t};\n") w("\trootObject = %s;\n" % self._id) w("}\n") def add_task_gen(self, tg): if not getattr(tg, 'mac_app', False): self.targets.append(PBXLegacyTarget('build', tg.name)) else: target = PBXNativeTarget('build', tg.name, tg.link_task.outputs[0].change_ext('.app'), tg.env) self.targets.append(target) self._output.children.append(target.productReference) class xcode(Build.BuildContext): cmd = 'xcode' fun = 'build' def collect_source(self, tg): source_files = tg.to_nodes(getattr(tg, 'source', [])) plist_files = tg.to_nodes(getattr(tg, 'mac_plist', [])) resource_files = [tg.path.find_node(i) for i in Utils.to_list(getattr(tg, 'mac_resources', []))] include_dirs = Utils.to_list(getattr(tg, 'includes', [])) + Utils.to_list(getattr(tg, 'export_dirs', [])) include_files = [] for x in include_dirs: if not isinstance(x, str): include_files.append(x) continue d = tg.path.find_node(x) if d: lst = [y for y in d.ant_glob(HEADERS_GLOB, flat=False)] include_files.extend(lst) # remove duplicates source = list(set(source_files + plist_files + resource_files + include_files)) source.sort(key=lambda x: x.abspath()) return source def execute(self): """ Entry point """ self.restore() if not self.all_envs: self.load_envs() self.recurse([self.run_dir]) appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) p = PBXProject(appname, ('Xcode 3.2', 46)) for g in self.groups: for tg in g: if not isinstance(tg, TaskGen.task_gen): continue tg.post() features = Utils.to_list(getattr(tg, 'features', '')) group = PBXGroup(tg.name) group.add(tg.path, self.collect_source(tg)) p.mainGroup.children.append(group) if 'cprogram' or 'cxxprogram' in features: p.add_task_gen(tg) # targets that don't produce the executable but that you might want to run p.targets.append(PBXLegacyTarget('configure')) p.targets.append(PBXLegacyTarget('dist')) p.targets.append(PBXLegacyTarget('install')) p.targets.append(PBXLegacyTarget('check')) node = self.srcnode.make_node('%s.xcodeproj' % appname) node.mkdir() node = node.make_node('project.pbxproj') p.write(open(node.abspath(), 'w')) 1.9.12~dfsg/waflib/ansiterm.py0000644000000000000000000002521213214314510015002 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 """ Emulate a vt100 terminal in cmd.exe By wrapping sys.stdout / sys.stderr with Ansiterm, the vt100 escape characters will be interpreted and the equivalent actions will be performed with Win32 console commands. """ import os, re, sys from waflib import Utils wlock = Utils.threading.Lock() try: from ctypes import Structure, windll, c_short, c_ushort, c_ulong, c_int, byref, c_wchar, POINTER, c_long except ImportError: class AnsiTerm(object): def __init__(self, stream): self.stream = stream try: self.errors = self.stream.errors except AttributeError: pass # python 2.5 self.encoding = self.stream.encoding def write(self, txt): try: wlock.acquire() self.stream.write(txt) self.stream.flush() finally: wlock.release() def fileno(self): return self.stream.fileno() def flush(self): self.stream.flush() def isatty(self): return self.stream.isatty() else: class COORD(Structure): _fields_ = [("X", c_short), ("Y", c_short)] class SMALL_RECT(Structure): _fields_ = [("Left", c_short), ("Top", c_short), ("Right", c_short), ("Bottom", c_short)] class CONSOLE_SCREEN_BUFFER_INFO(Structure): _fields_ = [("Size", COORD), ("CursorPosition", COORD), ("Attributes", c_ushort), ("Window", SMALL_RECT), ("MaximumWindowSize", COORD)] class CONSOLE_CURSOR_INFO(Structure): _fields_ = [('dwSize', c_ulong), ('bVisible', c_int)] try: _type = unicode except NameError: _type = str to_int = lambda number, default: number and int(number) or default STD_OUTPUT_HANDLE = -11 STD_ERROR_HANDLE = -12 windll.kernel32.GetStdHandle.argtypes = [c_ulong] windll.kernel32.GetStdHandle.restype = c_ulong windll.kernel32.GetConsoleScreenBufferInfo.argtypes = [c_ulong, POINTER(CONSOLE_SCREEN_BUFFER_INFO)] windll.kernel32.GetConsoleScreenBufferInfo.restype = c_long windll.kernel32.SetConsoleTextAttribute.argtypes = [c_ulong, c_ushort] windll.kernel32.SetConsoleTextAttribute.restype = c_long windll.kernel32.FillConsoleOutputCharacterW.argtypes = [c_ulong, c_wchar, c_ulong, POINTER(COORD), POINTER(c_ulong)] windll.kernel32.FillConsoleOutputCharacterW.restype = c_long windll.kernel32.FillConsoleOutputAttribute.argtypes = [c_ulong, c_ushort, c_ulong, POINTER(COORD), POINTER(c_ulong) ] windll.kernel32.FillConsoleOutputAttribute.restype = c_long windll.kernel32.SetConsoleCursorPosition.argtypes = [c_ulong, POINTER(COORD) ] windll.kernel32.SetConsoleCursorPosition.restype = c_long windll.kernel32.SetConsoleCursorInfo.argtypes = [c_ulong, POINTER(CONSOLE_CURSOR_INFO)] windll.kernel32.SetConsoleCursorInfo.restype = c_long class AnsiTerm(object): """ emulate a vt100 terminal in cmd.exe """ def __init__(self, s): self.stream = s try: self.errors = s.errors except AttributeError: pass # python2.5 self.encoding = s.encoding self.cursor_history = [] handle = (s.fileno() == 2) and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE self.hconsole = windll.kernel32.GetStdHandle(handle) self._sbinfo = CONSOLE_SCREEN_BUFFER_INFO() self._csinfo = CONSOLE_CURSOR_INFO() windll.kernel32.GetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) # just to double check that the console is usable self._orig_sbinfo = CONSOLE_SCREEN_BUFFER_INFO() r = windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self._orig_sbinfo)) self._isatty = r == 1 def screen_buffer_info(self): """ Updates self._sbinfo and returns it """ windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self._sbinfo)) return self._sbinfo def clear_line(self, param): mode = param and int(param) or 0 sbinfo = self.screen_buffer_info() if mode == 1: # Clear from begining of line to cursor position line_start = COORD(0, sbinfo.CursorPosition.Y) line_length = sbinfo.Size.X elif mode == 2: # Clear entire line line_start = COORD(sbinfo.CursorPosition.X, sbinfo.CursorPosition.Y) line_length = sbinfo.Size.X - sbinfo.CursorPosition.X else: # Clear from cursor position to end of line line_start = sbinfo.CursorPosition line_length = sbinfo.Size.X - sbinfo.CursorPosition.X chars_written = c_ulong() windll.kernel32.FillConsoleOutputCharacterW(self.hconsole, c_wchar(' '), line_length, line_start, byref(chars_written)) windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, line_length, line_start, byref(chars_written)) def clear_screen(self, param): mode = to_int(param, 0) sbinfo = self.screen_buffer_info() if mode == 1: # Clear from begining of screen to cursor position clear_start = COORD(0, 0) clear_length = sbinfo.CursorPosition.X * sbinfo.CursorPosition.Y elif mode == 2: # Clear entire screen and return cursor to home clear_start = COORD(0, 0) clear_length = sbinfo.Size.X * sbinfo.Size.Y windll.kernel32.SetConsoleCursorPosition(self.hconsole, clear_start) else: # Clear from cursor position to end of screen clear_start = sbinfo.CursorPosition clear_length = ((sbinfo.Size.X - sbinfo.CursorPosition.X) + sbinfo.Size.X * (sbinfo.Size.Y - sbinfo.CursorPosition.Y)) chars_written = c_ulong() windll.kernel32.FillConsoleOutputCharacterW(self.hconsole, c_wchar(' '), clear_length, clear_start, byref(chars_written)) windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, clear_length, clear_start, byref(chars_written)) def push_cursor(self, param): sbinfo = self.screen_buffer_info() self.cursor_history.append(sbinfo.CursorPosition) def pop_cursor(self, param): if self.cursor_history: old_pos = self.cursor_history.pop() windll.kernel32.SetConsoleCursorPosition(self.hconsole, old_pos) def set_cursor(self, param): y, sep, x = param.partition(';') x = to_int(x, 1) - 1 y = to_int(y, 1) - 1 sbinfo = self.screen_buffer_info() new_pos = COORD( min(max(0, x), sbinfo.Size.X), min(max(0, y), sbinfo.Size.Y) ) windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) def set_column(self, param): x = to_int(param, 1) - 1 sbinfo = self.screen_buffer_info() new_pos = COORD( min(max(0, x), sbinfo.Size.X), sbinfo.CursorPosition.Y ) windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) def move_cursor(self, x_offset=0, y_offset=0): sbinfo = self.screen_buffer_info() new_pos = COORD( min(max(0, sbinfo.CursorPosition.X + x_offset), sbinfo.Size.X), min(max(0, sbinfo.CursorPosition.Y + y_offset), sbinfo.Size.Y) ) windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) def move_up(self, param): self.move_cursor(y_offset = -to_int(param, 1)) def move_down(self, param): self.move_cursor(y_offset = to_int(param, 1)) def move_left(self, param): self.move_cursor(x_offset = -to_int(param, 1)) def move_right(self, param): self.move_cursor(x_offset = to_int(param, 1)) def next_line(self, param): sbinfo = self.screen_buffer_info() self.move_cursor( x_offset = -sbinfo.CursorPosition.X, y_offset = to_int(param, 1) ) def prev_line(self, param): sbinfo = self.screen_buffer_info() self.move_cursor( x_offset = -sbinfo.CursorPosition.X, y_offset = -to_int(param, 1) ) def rgb2bgr(self, c): return ((c&1) << 2) | (c&2) | ((c&4)>>2) def set_color(self, param): cols = param.split(';') sbinfo = self.screen_buffer_info() attr = sbinfo.Attributes for c in cols: c = to_int(c, 0) if 29 < c < 38: # fgcolor attr = (attr & 0xfff0) | self.rgb2bgr(c - 30) elif 39 < c < 48: # bgcolor attr = (attr & 0xff0f) | (self.rgb2bgr(c - 40) << 4) elif c == 0: # reset attr = self._orig_sbinfo.Attributes elif c == 1: # strong attr |= 0x08 elif c == 4: # blink not available -> bg intensity attr |= 0x80 elif c == 7: # negative attr = (attr & 0xff88) | ((attr & 0x70) >> 4) | ((attr & 0x07) << 4) windll.kernel32.SetConsoleTextAttribute(self.hconsole, attr) def show_cursor(self,param): self._csinfo.bVisible = 1 windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) def hide_cursor(self,param): self._csinfo.bVisible = 0 windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) ansi_command_table = { 'A': move_up, 'B': move_down, 'C': move_right, 'D': move_left, 'E': next_line, 'F': prev_line, 'G': set_column, 'H': set_cursor, 'f': set_cursor, 'J': clear_screen, 'K': clear_line, 'h': show_cursor, 'l': hide_cursor, 'm': set_color, 's': push_cursor, 'u': pop_cursor, } # Match either the escape sequence or text not containing escape sequence ansi_tokens = re.compile('(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))') def write(self, text): try: wlock.acquire() if self._isatty: for param, cmd, txt in self.ansi_tokens.findall(text): if cmd: cmd_func = self.ansi_command_table.get(cmd) if cmd_func: cmd_func(self, param) else: self.writeconsole(txt) else: # no support for colors in the console, just output the text: # eclipse or msys may be able to interpret the escape sequences self.stream.write(text) finally: wlock.release() def writeconsole(self, txt): chars_written = c_ulong() writeconsole = windll.kernel32.WriteConsoleA if isinstance(txt, _type): writeconsole = windll.kernel32.WriteConsoleW # MSDN says that there is a shared buffer of 64 KB for the console # writes. Attempt to not get ERROR_NOT_ENOUGH_MEMORY, see waf issue #746 done = 0 todo = len(txt) chunk = 32<<10 while todo != 0: doing = min(chunk, todo) buf = txt[done:done+doing] r = writeconsole(self.hconsole, buf, doing, byref(chars_written), None) if r == 0: chunk >>= 1 continue done += doing todo -= doing def fileno(self): return self.stream.fileno() def flush(self): pass def isatty(self): return self._isatty if sys.stdout.isatty() or sys.stderr.isatty(): handle = sys.stdout.isatty() and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE console = windll.kernel32.GetStdHandle(handle) sbinfo = CONSOLE_SCREEN_BUFFER_INFO() def get_term_cols(): windll.kernel32.GetConsoleScreenBufferInfo(console, byref(sbinfo)) # TODO Issue 1401 return sbinfo.Size.X - 1 # just try and see try: import struct, fcntl, termios except ImportError: pass else: if (sys.stdout.isatty() or sys.stderr.isatty()) and os.environ.get('TERM', '') not in ('dumb', 'emacs'): FD = sys.stdout.isatty() and sys.stdout.fileno() or sys.stderr.fileno() def fun(): return struct.unpack("HHHH", fcntl.ioctl(FD, termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)))[1] try: fun() except Exception as e: pass else: get_term_cols = fun 1.9.12~dfsg/waflib/Configure.py0000644000000000000000000004453413214314510015111 0ustar rootroot#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2010 (ita) """ Configuration system A :py:class:`waflib.Configure.ConfigurationContext` instance is created when ``waf configure`` is called, it is used to: * create data dictionaries (ConfigSet instances) * store the list of modules to import * hold configuration routines such as ``find_program``, etc """ import os, shlex, sys, time, re, shutil from waflib import ConfigSet, Utils, Options, Logs, Context, Build, Errors BREAK = 'break' """In case of a configuration error, break""" CONTINUE = 'continue' """In case of a configuration error, continue""" WAF_CONFIG_LOG = 'config.log' """Name of the configuration log file""" autoconfig = False """Execute the configuration automatically""" conf_template = '''# project %(app)s configured on %(now)s by # waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s) # using %(args)s #''' class ConfigurationContext(Context.Context): '''configures the project''' cmd = 'configure' error_handlers = [] """ Additional functions to handle configuration errors """ def __init__(self, **kw): super(ConfigurationContext, self).__init__(**kw) self.environ = dict(os.environ) self.all_envs = {} self.top_dir = None self.out_dir = None self.tools = [] # tools loaded in the configuration, and that will be loaded when building self.hash = 0 self.files = [] self.tool_cache = [] self.setenv('') def setenv(self, name, env=None): """ Set a new config set for conf.env. If a config set of that name already exists, recall it without modification. The name is the filename prefix to save to ``c4che/NAME_cache.py``, and it is also used as *variants* by the build commands. Though related to variants, whatever kind of data may be stored in the config set:: def configure(cfg): cfg.env.ONE = 1 cfg.setenv('foo') cfg.env.ONE = 2 def build(bld): 2 == bld.env_of_name('foo').ONE :param name: name of the configuration set :type name: string :param env: ConfigSet to copy, or an empty ConfigSet is created :type env: :py:class:`waflib.ConfigSet.ConfigSet` """ if name not in self.all_envs or env: if not env: env = ConfigSet.ConfigSet() self.prepare_env(env) else: env = env.derive() self.all_envs[name] = env self.variant = name def get_env(self): """Getter for the env property""" return self.all_envs[self.variant] def set_env(self, val): """Setter for the env property""" self.all_envs[self.variant] = val env = property(get_env, set_env) def init_dirs(self): """ Initialize the project directory and the build directory """ top = self.top_dir if not top: top = Options.options.top if not top: top = getattr(Context.g_module, Context.TOP, None) if not top: top = self.path.abspath() top = os.path.abspath(top) self.srcnode = (os.path.isabs(top) and self.root or self.path).find_dir(top) assert(self.srcnode) out = self.out_dir if not out: out = Options.options.out if not out: out = getattr(Context.g_module, Context.OUT, None) if not out: out = Options.lockfile.replace('.lock-waf_%s_' % sys.platform, '').replace('.lock-waf', '') # someone can be messing with symlinks out = os.path.realpath(out) self.bldnode = (os.path.isabs(out) and self.root or self.path).make_node(out) self.bldnode.mkdir() if not os.path.isdir(self.bldnode.abspath()): conf.fatal('Could not create the build directory %s' % self.bldnode.abspath()) def execute(self): """ See :py:func:`waflib.Context.Context.execute` """ self.init_dirs() self.cachedir = self.bldnode.make_node(Build.CACHE_DIR) self.cachedir.mkdir() path = os.path.join(self.bldnode.abspath(), WAF_CONFIG_LOG) self.logger = Logs.make_logger(path, 'cfg') app = getattr(Context.g_module, 'APPNAME', '') if app: ver = getattr(Context.g_module, 'VERSION', '') if ver: app = "%s (%s)" % (app, ver) params = {'now': time.ctime(), 'pyver': sys.hexversion, 'systype': sys.platform, 'args': " ".join(sys.argv), 'wafver': Context.WAFVERSION, 'abi': Context.ABI, 'app': app} self.to_log(conf_template % params) self.msg('Setting top to', self.srcnode.abspath()) self.msg('Setting out to', self.bldnode.abspath()) if id(self.srcnode) == id(self.bldnode): Logs.warn('Setting top == out (remember to use "update_outputs")') elif id(self.path) != id(self.srcnode): if self.srcnode.is_child_of(self.path): Logs.warn('Are you certain that you do not want to set top="." ?') super(ConfigurationContext, self).execute() self.store() Context.top_dir = self.srcnode.abspath() Context.out_dir = self.bldnode.abspath() # this will write a configure lock so that subsequent builds will # consider the current path as the root directory (see prepare_impl). # to remove: use 'waf distclean' env = ConfigSet.ConfigSet() env['argv'] = sys.argv env['options'] = Options.options.__dict__ env.run_dir = Context.run_dir env.top_dir = Context.top_dir env.out_dir = Context.out_dir # conf.hash & conf.files hold wscript files paths and hash # (used only by Configure.autoconfig) env['hash'] = self.hash env['files'] = self.files env['environ'] = dict(self.environ) if not self.env.NO_LOCK_IN_RUN and not getattr(Options.options, 'no_lock_in_run'): env.store(os.path.join(Context.run_dir, Options.lockfile)) if not self.env.NO_LOCK_IN_TOP and not getattr(Options.options, 'no_lock_in_top'): env.store(os.path.join(Context.top_dir, Options.lockfile)) if not self.env.NO_LOCK_IN_OUT and not getattr(Options.options, 'no_lock_in_out'): env.store(os.path.join(Context.out_dir, Options.lockfile)) def prepare_env(self, env): """ Insert *PREFIX*, *BINDIR* and *LIBDIR* values into ``env`` :type env: :py:class:`waflib.ConfigSet.ConfigSet` :param env: a ConfigSet, usually ``conf.env`` """ if not env.PREFIX: if Options.options.prefix or Utils.is_win32: env.PREFIX = Utils.sane_path(Options.options.prefix) else: env.PREFIX = '' if not env.BINDIR: if Options.options.bindir: env.BINDIR = Utils.sane_path(Options.options.bindir) else: env.BINDIR = Utils.subst_vars('${PREFIX}/bin', env) if not env.LIBDIR: if Options.options.libdir: env.LIBDIR = Utils.sane_path(Options.options.libdir) else: env.LIBDIR = Utils.subst_vars('${PREFIX}/lib%s' % Utils.lib64(), env) def store(self): """Save the config results into the cache file""" n = self.cachedir.make_node('build.config.py') n.write('version = 0x%x\ntools = %r\n' % (Context.HEXVERSION, self.tools)) if not self.all_envs: self.fatal('nothing to store in the configuration context!') for key in self.all_envs: tmpenv = self.all_envs[key] tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX)) def load(self, input, tooldir=None, funs=None, with_sys_path=True): """ Load Waf tools, which will be imported whenever a build is started. :param input: waf tools to import :type input: list of string :param tooldir: paths for the imports :type tooldir: list of string :param funs: functions to execute from the waf tools :type funs: list of string """ tools = Utils.to_list(input) if tooldir: tooldir = Utils.to_list(tooldir) for tool in tools: # avoid loading the same tool more than once with the same functions # used by composite projects mag = (tool, id(self.env), tooldir, funs) if mag in self.tool_cache: self.to_log('(tool %s is already loaded, skipping)' % tool) continue self.tool_cache.append(mag) module = None try: module = Context.load_tool(tool, tooldir, ctx=self, with_sys_path=with_sys_path) except ImportError as e: self.fatal('Could not load the Waf tool %r from %r\n%s' % (tool, sys.path, e)) except Exception as e: self.to_log('imp %r (%r & %r)' % (tool, tooldir, funs)) self.to_log(Utils.ex_stack()) raise if funs is not None: self.eval_rules(funs) else: func = getattr(module, 'configure', None) if func: if type(func) is type(Utils.readf): func(self) else: self.eval_rules(func) self.tools.append({'tool':tool, 'tooldir':tooldir, 'funs':funs}) def post_recurse(self, node): """ Records the path and a hash of the scripts visited, see :py:meth:`waflib.Context.Context.post_recurse` :param node: script :type node: :py:class:`waflib.Node.Node` """ super(ConfigurationContext, self).post_recurse(node) self.hash = Utils.h_list((self.hash, node.read('rb'))) self.files.append(node.abspath()) def eval_rules(self, rules): """ Execute the configuration tests. The method :py:meth:`waflib.Configure.ConfigurationContext.err_handler` is used to process the eventual exceptions :param rules: list of configuration method names :type rules: list of string """ self.rules = Utils.to_list(rules) for x in self.rules: f = getattr(self, x) if not f: self.fatal("No such method '%s'." % x) try: f() except Exception as e: ret = self.err_handler(x, e) if ret == BREAK: break elif ret == CONTINUE: continue else: raise def err_handler(self, fun, error): """ Error handler for the configuration tests, the default is to let the exception raise :param fun: configuration test :type fun: method :param error: exception :type error: exception """ pass def conf(f): """ Decorator: attach new configuration functions to :py:class:`waflib.Build.BuildContext` and :py:class:`waflib.Configure.ConfigurationContext`. The methods bound will accept a parameter named 'mandatory' to disable the configuration errors:: def configure(conf): conf.find_program('abc', mandatory=False) :param f: method to bind :type f: function """ def fun(*k, **kw): mandatory = True if 'mandatory' in kw: mandatory = kw['mandatory'] del kw['mandatory'] try: return f(*k, **kw) except Errors.ConfigurationError: if mandatory: raise fun.__name__ = f.__name__ setattr(ConfigurationContext, f.__name__, fun) setattr(Build.BuildContext, f.__name__, fun) return f @conf def add_os_flags(self, var, dest=None, dup=True): """ Import operating system environment values into ``conf.env`` dict:: def configure(conf): conf.add_os_flags('CFLAGS') :param var: variable to use :type var: string :param dest: destination variable, by default the same as var :type dest: string :param dup: add the same set of flags again :type dup: bool """ try: flags = shlex.split(self.environ[var]) except KeyError: return # TODO: in waf 1.9, make dup=False the default if dup or ''.join(flags) not in ''.join(Utils.to_list(self.env[dest or var])): self.env.append_value(dest or var, flags) @conf def cmd_to_list(self, cmd): """ Detect if a command is written in pseudo shell like ``ccache g++`` and return a list. :param cmd: command :type cmd: a string or a list of string """ if isinstance(cmd, str) and cmd.find(' '): try: os.stat(cmd) except OSError: return shlex.split(cmd) else: return [cmd] return cmd @conf def check_waf_version(self, mini='1.7.99', maxi='1.9.0', **kw): """ Raise a Configuration error if the Waf version does not strictly match the given bounds:: conf.check_waf_version(mini='1.8.0', maxi='1.9.0') :type mini: number, tuple or string :param mini: Minimum required version :type maxi: number, tuple or string :param maxi: Maximum allowed version """ self.start_msg('Checking for waf version in %s-%s' % (str(mini), str(maxi)), **kw) ver = Context.HEXVERSION if Utils.num2ver(mini) > ver: self.fatal('waf version should be at least %r (%r found)' % (Utils.num2ver(mini), ver)) if Utils.num2ver(maxi) < ver: self.fatal('waf version should be at most %r (%r found)' % (Utils.num2ver(maxi), ver)) self.end_msg('ok', **kw) @conf def find_file(self, filename, path_list=[]): """ Find a file in a list of paths :param filename: name of the file to search for :param path_list: list of directories to search :return: the first occurrence filename or '' if filename could not be found """ for n in Utils.to_list(filename): for d in Utils.to_list(path_list): p = os.path.expanduser(os.path.join(d, n)) if os.path.exists(p): return p self.fatal('Could not find %r' % filename) @conf def find_program(self, filename, **kw): """ Search for a program on the operating system When var is used, you may set os.environ[var] to help find a specific program version, for example:: $ CC='ccache gcc' waf configure :param path_list: paths to use for searching :type param_list: list of string :param var: store the result to conf.env[var], by default use filename.upper() :type var: string :param ext: list of extensions for the binary (do not add an extension for portability) :type ext: list of string :param msg: name to display in the log, by default filename is used :type msg: string :param interpreter: interpreter for the program :type interpreter: ConfigSet variable key """ exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py') environ = kw.get('environ', getattr(self, 'environ', os.environ)) ret = '' filename = Utils.to_list(filename) msg = kw.get('msg', ', '.join(filename)) var = kw.get('var', '') if not var: var = re.sub(r'[-.]', '_', filename[0].upper()) path_list = kw.get('path_list', '') if path_list: path_list = Utils.to_list(path_list) else: path_list = environ.get('PATH', '').split(os.pathsep) if var in environ: filename = environ[var] if os.path.isfile(filename): # typical CC=/usr/bin/gcc waf configure build ret = [filename] else: # case CC='ccache gcc' waf configure build ret = self.cmd_to_list(filename) elif self.env[var]: # set by the user in the wscript file ret = self.env[var] ret = self.cmd_to_list(ret) else: if not ret: ret = self.find_binary(filename, exts.split(','), path_list) if not ret and Utils.winreg: ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename) if not ret and Utils.winreg: ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename) ret = self.cmd_to_list(ret) if ret: if len(ret) == 1: retmsg = ret[0] else: retmsg = ret else: retmsg = False self.msg("Checking for program '%s'" % msg, retmsg, **kw) if not kw.get('quiet', None): self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret)) if not ret: self.fatal(kw.get('errmsg', '') or 'Could not find the program %r' % filename) interpreter = kw.get('interpreter', None) if interpreter is None: if not Utils.check_exe(ret[0], env=environ): self.fatal('Program %r is not executable' % ret) self.env[var] = ret else: self.env[var] = self.env[interpreter] + ret return ret @conf def find_binary(self, filenames, exts, paths): for f in filenames: for ext in exts: exe_name = f + ext if os.path.isabs(exe_name): if os.path.isfile(exe_name): return exe_name else: for path in paths: x = os.path.expanduser(os.path.join(path, exe_name)) if os.path.isfile(x): return x return None @conf def run_build(self, *k, **kw): """ Create a temporary build context to execute a build. A reference to that build context is kept on self.test_bld for debugging purposes, and you should not rely on it too much (read the note on the cache below). The parameters given in the arguments to this function are passed as arguments for a single task generator created in the build. Only three parameters are obligatory: :param features: features to pass to a task generator created in the build :type features: list of string :param compile_filename: file to create for the compilation (default: *test.c*) :type compile_filename: string :param code: code to write in the filename to compile :type code: string Though this function returns *0* by default, the build may set an attribute named *retval* on the build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example. This function also provides a limited cache. To use it, provide the following option:: def options(opt): opt.add_option('--confcache', dest='confcache', default=0, action='count', help='Use a configuration cache') And execute the configuration with the following command-line:: $ waf configure --confcache """ lst = [str(v) for (p, v) in kw.items() if p != 'env'] h = Utils.h_list(lst) dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h) try: os.makedirs(dir) except OSError: pass try: os.stat(dir) except OSError: self.fatal('cannot use the configuration test folder %r' % dir) cachemode = getattr(Options.options, 'confcache', None) if cachemode == 1: try: proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build')) except OSError: pass except IOError: pass else: ret = proj['cache_run_build'] if isinstance(ret, str) and ret.startswith('Test does not build'): self.fatal(ret) return ret bdir = os.path.join(dir, 'testbuild') if not os.path.exists(bdir): os.makedirs(bdir) self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir) bld.init_dirs() bld.progress_bar = 0 bld.targets = '*' bld.logger = self.logger bld.all_envs.update(self.all_envs) # not really necessary bld.env = kw['env'] # OMG huge hack bld.kw = kw bld.conf = self kw['build_fun'](bld) ret = -1 try: try: bld.compile() except Errors.WafError: ret = 'Test does not build: %s' % Utils.ex_stack() self.fatal(ret) else: ret = getattr(bld, 'retval', 0) finally: if cachemode == 1: # cache the results each time proj = ConfigSet.ConfigSet() proj['cache_run_build'] = ret proj.store(os.path.join(dir, 'cache_run_build')) else: shutil.rmtree(dir) return ret @conf def ret_msg(self, msg, args): if isinstance(msg, str): return msg return msg(args) @conf def test(self, *k, **kw): if not 'env' in kw: kw['env'] = self.env.derive() # validate_c for example if kw.get('validate', None): kw['validate'](kw) self.start_msg(kw['msg'], **kw) ret = None try: ret = self.run_build(*k, **kw) except self.errors.ConfigurationError: self.end_msg(kw['errmsg'], 'YELLOW', **kw) if Logs.verbose > 1: raise else: self.fatal('The configuration failed') else: kw['success'] = ret if kw.get('post_check', None): ret = kw['post_check'](kw) if ret: self.end_msg(kw['errmsg'], 'YELLOW', **kw) self.fatal('The configuration failed %r' % ret) else: self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) return ret 1.9.12~dfsg/dbus/0000755000000000000000000000000013214314510012275 5ustar rootroot1.9.12~dfsg/dbus/audio_reserve.c0000644000000000000000000000704413214314510015302 0ustar rootroot/* Copyright (C) 2009 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include "reserve.h" #include "audio_reserve.h" #include "jack/control.h" #define DEVICE_MAX 2 typedef struct reserved_audio_device { char device_name[64]; rd_device * reserved_device; } reserved_audio_device; static DBusConnection* gConnection = NULL; static reserved_audio_device gReservedDevice[DEVICE_MAX]; static int gReserveCount = 0; SERVER_EXPORT int audio_reservation_init() { DBusError error; dbus_error_init(&error); if (!(gConnection = dbus_bus_get(DBUS_BUS_SESSION, &error))) { jack_error("Failed to connect to session bus for device reservation: %s\n", error.message); jack_info("To bypass device reservation via session bus, set JACK_NO_AUDIO_RESERVATION=1 prior to starting jackd.\n"); return -1; } jack_info("audio_reservation_init"); return 0; } SERVER_EXPORT int audio_reservation_finish() { if (gConnection) { dbus_connection_unref(gConnection); gConnection = NULL; jack_info("audio_reservation_finish"); } return 0; } SERVER_EXPORT bool audio_acquire(const char * device_name) { DBusError error; int ret; // Open DBus connection first time if (gReserveCount == 0) { if (audio_reservation_init() != 0) { return false; } } assert(gReserveCount < DEVICE_MAX); dbus_error_init(&error); if ((ret= rd_acquire( &gReservedDevice[gReserveCount].reserved_device, gConnection, device_name, "Jack audio server", INT32_MAX, NULL, &error)) < 0) { jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret))); dbus_error_free(&error); return false; } strcpy(gReservedDevice[gReserveCount].device_name, device_name); gReserveCount++; jack_info("Acquire audio card %s", device_name); return true; } SERVER_EXPORT void audio_release(const char * device_name) { int i; // Look for corresponding reserved device for (i = 0; i < DEVICE_MAX; i++) { if (strcmp(gReservedDevice[i].device_name, device_name) == 0) break; } if (i < DEVICE_MAX) { jack_info("Released audio card %s", device_name); rd_release(gReservedDevice[i].reserved_device); } else { jack_error("Audio card %s not found!!", device_name); } // Close DBus connection last time gReserveCount--; if (gReserveCount == 0) audio_reservation_finish(); } SERVER_EXPORT void audio_reserve_loop() { if (gConnection != NULL) { while (dbus_connection_read_write_dispatch (gConnection, -1)) ; // empty loop body } } 1.9.12~dfsg/dbus/params.c0000644000000000000000000004700313214314510013730 0ustar rootroot/* -*- Mode: C ; c-basic-offset: 4 -*- */ /* Copyright (C) 2011 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Parameter addresses: * * "engine" * "engine", "driver" * "engine", "realtime" * "engine", ...more engine parameters * * "driver", "device" * "driver", ...more driver parameters * * "drivers", "alsa", "device" * "drivers", "alsa", ...more alsa driver parameters * * "drivers", ...more drivers * * "internals", "netmanager", "multicast_ip" * "internals", "netmanager", ...more netmanager parameters * * "internals", ...more internals * */ #include #include #include #include #include "params.h" #include "controller_internal.h" #define PTNODE_ENGINE "engine" #define PTNODE_DRIVER "driver" #define PTNODE_DRIVERS "drivers" #define PTNODE_INTERNALS "internals" struct jack_parameter_container { struct list_head siblings; char * name; struct jack_parameter_container * symlink; bool leaf; struct list_head children; void * obj; }; struct jack_params { jackctl_server_t * server; struct jack_parameter_container root; struct list_head * drivers_ptr; uint32_t drivers_count; struct jack_parameter_container * driver_ptr; bool driver_set; /* whether driver is manually set, if false - DEFAULT_DRIVER is auto set */ }; static bool controlapi_parameter_is_set(void * obj) { return jackctl_parameter_is_set((jackctl_parameter_t *)obj); } static bool controlapi_parameter_reset(void * obj) { return jackctl_parameter_reset((jackctl_parameter_t *)obj); } union jackctl_parameter_value controlapi_parameter_get_value(void * obj) { return jackctl_parameter_get_value((jackctl_parameter_t *)obj); } bool controlapi_parameter_set_value(void * obj, const union jackctl_parameter_value * value_ptr) { return jackctl_parameter_set_value((jackctl_parameter_t *)obj, value_ptr); } union jackctl_parameter_value controlapi_parameter_get_default_value(void * obj) { return jackctl_parameter_get_default_value((jackctl_parameter_t *)obj); } static struct jack_parameter_container * create_container(struct list_head * parent_list_ptr, const char * name) { struct jack_parameter_container * container_ptr; container_ptr = malloc(sizeof(struct jack_parameter_container)); if (container_ptr == NULL) { jack_error("Ran out of memory trying to allocate struct jack_parameter_container"); goto fail; } container_ptr->name = strdup(name); if (container_ptr->name == NULL) { jack_error("Ran out of memory trying to strdup parameter container name"); goto free; } container_ptr->leaf = false; container_ptr->symlink = NULL; container_ptr->obj = NULL; INIT_LIST_HEAD(&container_ptr->children); list_add_tail(&container_ptr->siblings, parent_list_ptr); return container_ptr; free: free(container_ptr); fail: return NULL; } static bool add_controlapi_param(struct list_head * parent_list_ptr, jackctl_parameter_t * param) { struct jack_parameter * param_ptr; uint32_t i; param_ptr = malloc(sizeof(struct jack_parameter)); if (param_ptr == NULL) { jack_error("Ran out of memory trying to allocate struct jack_parameter"); goto fail; } param_ptr->ext = false; param_ptr->obj = param; param_ptr->vtable.is_set = controlapi_parameter_is_set; param_ptr->vtable.reset = controlapi_parameter_reset; param_ptr->vtable.get_value = controlapi_parameter_get_value; param_ptr->vtable.set_value = controlapi_parameter_set_value; param_ptr->vtable.get_default_value = controlapi_parameter_get_default_value; param_ptr->type = jackctl_parameter_get_type(param); param_ptr->name = jackctl_parameter_get_name(param); param_ptr->short_decr = jackctl_parameter_get_short_description(param); param_ptr->long_descr = jackctl_parameter_get_long_description(param); if (jackctl_parameter_has_range_constraint(param)) { param_ptr->constraint_flags = JACK_CONSTRAINT_FLAG_VALID; param_ptr->constraint_range = true; jackctl_parameter_get_range_constraint(param, ¶m_ptr->constraint.range.min, ¶m_ptr->constraint.range.max); } else if (jackctl_parameter_has_enum_constraint(param)) { param_ptr->constraint_flags = JACK_CONSTRAINT_FLAG_VALID; param_ptr->constraint_range = false; param_ptr->constraint.enumeration.count = jackctl_parameter_get_enum_constraints_count(param); param_ptr->constraint.enumeration.possible_values_array = malloc(sizeof(struct jack_parameter_enum) * param_ptr->constraint.enumeration.count); if (param_ptr->constraint.enumeration.possible_values_array == NULL) { goto free; } for (i = 0; i < param_ptr->constraint.enumeration.count; i++) { param_ptr->constraint.enumeration.possible_values_array[i].value = jackctl_parameter_get_enum_constraint_value(param, i); param_ptr->constraint.enumeration.possible_values_array[i].short_desc = jackctl_parameter_get_enum_constraint_description(param, i); } } else { param_ptr->constraint_flags = 0; goto add; } if (jackctl_parameter_constraint_is_strict(param)) { param_ptr->constraint_flags |= JACK_CONSTRAINT_FLAG_STRICT; } if (jackctl_parameter_constraint_is_fake_value(param)) { param_ptr->constraint_flags |= JACK_CONSTRAINT_FLAG_FAKE_VALUE; } add: list_add_tail(¶m_ptr->siblings, parent_list_ptr); return true; free: free(param_ptr); fail: return false; } static void free_params(struct list_head * parent_list_ptr) { struct jack_parameter * param_ptr; while (!list_empty(parent_list_ptr)) { param_ptr = list_entry(parent_list_ptr->next, struct jack_parameter, siblings); list_del(¶m_ptr->siblings); if (param_ptr->ext) { continue; } if ((param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_VALID) != 0 && !param_ptr->constraint_range && param_ptr->constraint.enumeration.possible_values_array != NULL) { free(param_ptr->constraint.enumeration.possible_values_array); } free(param_ptr); } } static void free_containers(struct list_head * parent_list_ptr) { struct jack_parameter_container * container_ptr; while (!list_empty(parent_list_ptr)) { container_ptr = list_entry(parent_list_ptr->next, struct jack_parameter_container, siblings); list_del(&container_ptr->siblings); if (container_ptr->leaf) { free_params(&container_ptr->children); } else { free_containers(&container_ptr->children); } free(container_ptr->name); free(container_ptr); } } static struct jack_parameter_container * find_container(struct jack_parameter_container * parent_ptr, const char * const * address, int max_depth) { struct list_head * node_ptr; struct jack_parameter_container * container_ptr; if (max_depth == 0 || *address == NULL) { return parent_ptr; } if (parent_ptr->leaf) { return NULL; } if (max_depth > 0) { max_depth--; } list_for_each(node_ptr, &parent_ptr->children) { container_ptr = list_entry(node_ptr, struct jack_parameter_container, siblings); if (strcmp(container_ptr->name, *address) == 0) { if (container_ptr->symlink != NULL) { container_ptr = container_ptr->symlink; } return find_container(container_ptr, address + 1, max_depth); } } return NULL; } static bool init_leaf(struct list_head * parent_list_ptr, const char * name, const JSList * params_list, void * obj) { struct jack_parameter_container * container_ptr; container_ptr = create_container(parent_list_ptr, name); if (container_ptr == NULL) { return false; } container_ptr->leaf = true; container_ptr->obj = obj; while (params_list) { if (!add_controlapi_param(&container_ptr->children, params_list->data)) { return false; } params_list = jack_slist_next(params_list); } return true; } static bool init_engine(struct jack_params * params_ptr) { return init_leaf(¶ms_ptr->root.children, PTNODE_ENGINE, jackctl_server_get_parameters(params_ptr->server), NULL); } static bool init_drivers(struct jack_params * params_ptr) { const JSList * list; struct jack_parameter_container * container_ptr; container_ptr = create_container(¶ms_ptr->root.children, PTNODE_DRIVERS); if (container_ptr == NULL) { return false; } params_ptr->drivers_ptr = &container_ptr->children; params_ptr->drivers_count = 0; list = jackctl_server_get_drivers_list(params_ptr->server); while (list) { if (!init_leaf(&container_ptr->children, jackctl_driver_get_name(list->data), jackctl_driver_get_parameters(list->data), list->data)) { return false; } params_ptr->drivers_count++; list = jack_slist_next(list); } return true; } static bool init_internals(struct jack_params * params_ptr) { const JSList * list; struct jack_parameter_container * container_ptr; container_ptr = create_container(¶ms_ptr->root.children, PTNODE_INTERNALS); if (container_ptr == NULL) { return false; } list = jackctl_server_get_internals_list(params_ptr->server); while (list) { if (!init_leaf(&container_ptr->children, jackctl_internal_get_name(list->data), jackctl_internal_get_parameters(list->data), NULL)) { return false; } list = jack_slist_next(list); } return true; } static bool init_driver(struct jack_params * params_ptr) { struct jack_parameter_container * container_ptr; container_ptr = create_container(¶ms_ptr->root.children, PTNODE_DRIVER); if (container_ptr == NULL) { return false; } params_ptr->driver_ptr = container_ptr; return true; } #define params_ptr ((struct jack_params *)obj) static bool engine_driver_parameter_is_set(void * obj) { return params_ptr->driver_set; } static bool engine_driver_parameter_reset(void * obj) { if (!jack_params_set_driver(obj, DEFAULT_DRIVER)) { return false; } params_ptr->driver_set = false; return true; } union jackctl_parameter_value engine_driver_parameter_get_value(void * obj) { union jackctl_parameter_value value; strcpy(value.str, params_ptr->driver_ptr->symlink->name); return value; } bool engine_driver_parameter_set_value(void * obj, const union jackctl_parameter_value * value_ptr) { return jack_params_set_driver(obj, value_ptr->str); } union jackctl_parameter_value engine_driver_parameter_get_default_value(void * obj) { union jackctl_parameter_value value; strcpy(value.str, DEFAULT_DRIVER); return value; } #undef params_ptr static bool add_engine_driver_enum_constraint(void * context, const char * name) { strcpy((*((struct jack_parameter_enum **)context))->value.str, name); (*((struct jack_parameter_enum **)context))->short_desc = name; (*((struct jack_parameter_enum **)context))++; return true; } static bool init_engine_driver_parameter(struct jack_params * params_ptr) { struct jack_parameter * param_ptr; const char * address[PARAM_ADDRESS_SIZE] = {PTNODE_ENGINE, NULL}; struct jack_parameter_container * engine_ptr; struct jack_parameter_enum * possible_value; engine_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); if (engine_ptr == NULL) { return false; } param_ptr = malloc(sizeof(struct jack_parameter)); if (param_ptr == NULL) { jack_error("Ran out of memory trying to allocate struct jack_parameter"); goto fail; } param_ptr->ext = false; param_ptr->obj = params_ptr; param_ptr->vtable.is_set = engine_driver_parameter_is_set; param_ptr->vtable.reset = engine_driver_parameter_reset; param_ptr->vtable.get_value = engine_driver_parameter_get_value; param_ptr->vtable.set_value = engine_driver_parameter_set_value; param_ptr->vtable.get_default_value = engine_driver_parameter_get_default_value; param_ptr->type = JackParamString; param_ptr->name = "driver"; param_ptr->short_decr = "Driver to use"; param_ptr->long_descr = ""; param_ptr->constraint_flags = JACK_CONSTRAINT_FLAG_VALID | JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE; param_ptr->constraint_range = false; param_ptr->constraint.enumeration.count = params_ptr->drivers_count; param_ptr->constraint.enumeration.possible_values_array = malloc(sizeof(struct jack_parameter_enum) * params_ptr->drivers_count); if (param_ptr->constraint.enumeration.possible_values_array == NULL) { goto free; } address[0] = PTNODE_DRIVERS; possible_value = param_ptr->constraint.enumeration.possible_values_array; jack_params_iterate_container((jack_params_handle)params_ptr, address, add_engine_driver_enum_constraint, &possible_value); list_add(¶m_ptr->siblings, &engine_ptr->children); return true; free: free(param_ptr); fail: return false; } jack_params_handle jack_params_create(jackctl_server_t * server) { struct jack_params * params_ptr; params_ptr = malloc(sizeof(struct jack_params)); if (params_ptr == NULL) { jack_error("Ran out of memory trying to allocate struct jack_params"); return NULL; } params_ptr->server = server; INIT_LIST_HEAD(¶ms_ptr->root.children); params_ptr->root.leaf = false; params_ptr->root.name = NULL; if (!init_engine(params_ptr) || !init_drivers(params_ptr) || !init_driver(params_ptr) || !init_engine_driver_parameter(params_ptr) || !jack_params_set_driver((jack_params_handle)params_ptr, DEFAULT_DRIVER) || !init_internals(params_ptr)) { jack_params_destroy((jack_params_handle)params_ptr); return NULL; } params_ptr->driver_set = false; assert(strcmp(params_ptr->driver_ptr->symlink->name, DEFAULT_DRIVER) == 0); return (jack_params_handle)params_ptr; } #define params_ptr ((struct jack_params *)params) void jack_params_destroy(jack_params_handle params) { free_containers(¶ms_ptr->root.children); free(params); } bool jack_params_set_driver(jack_params_handle params, const char * name) { struct list_head * node_ptr; struct jack_parameter_container * container_ptr; list_for_each(node_ptr, params_ptr->drivers_ptr) { container_ptr = list_entry(node_ptr, struct jack_parameter_container, siblings); if (strcmp(container_ptr->name, name) == 0) { params_ptr->driver_ptr->symlink = container_ptr; params_ptr->driver_set = true; return true; } } return false; } jackctl_driver_t * jack_params_get_driver(jack_params_handle params) { return params_ptr->driver_ptr->symlink->obj; } bool jack_params_check_address(jack_params_handle params, const char * const * address, bool want_leaf) { struct jack_parameter_container * container_ptr; container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); if (container_ptr == NULL) { return false; } if (want_leaf && !container_ptr->leaf) { return false; } return true; } bool jack_params_is_leaf_container(jack_params_handle params, const char * const * address) { struct jack_parameter_container * container_ptr; container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); if (container_ptr == NULL) { assert(false); return false; } return container_ptr->leaf; } bool jack_params_iterate_container( jack_params_handle params, const char * const * address, bool (* callback)(void * context, const char * name), void * context) { struct jack_parameter_container * container_ptr; struct list_head * node_ptr; const char * name; container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); if (container_ptr == NULL) { assert(false); return true; } list_for_each(node_ptr, &container_ptr->children) { if (container_ptr->leaf) { name = list_entry(node_ptr, struct jack_parameter, siblings)->name; } else { name = list_entry(node_ptr, struct jack_parameter_container, siblings)->name; } if (!callback(context, name)) { return false; } } return true; } bool jack_params_iterate_params( jack_params_handle params, const char * const * address, bool (* callback)(void * context, const struct jack_parameter * param_ptr), void * context) { struct jack_parameter_container * container_ptr; struct list_head * node_ptr; struct jack_parameter * param_ptr; container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); if (container_ptr == NULL || !container_ptr->leaf) { assert(false); return true; } list_for_each(node_ptr, &container_ptr->children) { param_ptr = list_entry(node_ptr, struct jack_parameter, siblings); if (!callback(context, param_ptr)) { return false; } } return true; } const struct jack_parameter * jack_params_get_parameter(jack_params_handle params, const char * const * address) { int depth; struct jack_parameter_container * container_ptr; struct list_head * node_ptr; struct jack_parameter * param_ptr; for (depth = 0; depth < PARAM_ADDRESS_SIZE; depth++) { if (address[depth] == NULL) { break; } } depth--; container_ptr = find_container(¶ms_ptr->root, address, depth); if (container_ptr == NULL || !container_ptr->leaf) { return NULL; } list_for_each(node_ptr, &container_ptr->children) { param_ptr = list_entry(node_ptr, struct jack_parameter, siblings); if (strcmp(param_ptr->name, address[depth]) == 0) { return param_ptr; } } return NULL; } void jack_params_add_parameter(jack_params_handle params, const char * const * address, bool end, struct jack_parameter * param_ptr) { struct jack_parameter_container * container_ptr; container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); if (container_ptr == NULL || !container_ptr->leaf) { assert(false); return; } param_ptr->ext = true; if (end) { list_add_tail(¶m_ptr->siblings, &container_ptr->children); } else { list_add(¶m_ptr->siblings, &container_ptr->children); } return; } #undef params_ptr 1.9.12~dfsg/dbus/sigsegv.h0000644000000000000000000000015713214314510014120 0ustar rootroot#ifndef __SIGSEGV_H__ #define __SIGSEGV_H__ #ifdef __cplusplus extern "C" #endif int setup_sigsegv(); #endif 1.9.12~dfsg/dbus/controller_iface_transport.c0000644000000000000000000000221113214314510020063 0ustar rootroot/* -*- Mode: C ; c-basic-offset: 4 -*- */ /* Copyright (C) 2008 Nedko Arnaudov Copyright (C) 2008 Juuso Alasuutari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #if defined(HAVE_CONFIG_H) #include "config.h" #endif #include #include #include #include #include #include "jackdbus.h" JACK_DBUS_METHODS_BEGIN JACK_DBUS_METHODS_END JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_transport, "org.jackaudio.JackTransport") JACK_DBUS_IFACE_EXPOSE_METHODS JACK_DBUS_IFACE_END 1.9.12~dfsg/dbus/controller.h0000644000000000000000000000215213214314510014631 0ustar rootroot/* -*- Mode: C ; c-basic-offset: 4 -*- */ /* Copyright (C) 2007 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef CONTROLLER_H__2CC80B1E_8D5D_45E3_A9D8_9086DDF68BB5__INCLUDED #define CONTROLLER_H__2CC80B1E_8D5D_45E3_A9D8_9086DDF68BB5__INCLUDED void * jack_controller_create( DBusConnection *connection); void jack_controller_run( void *controller_ptr); void jack_controller_destroy( void *controller_ptr); #endif /* #ifndef CONTROLLER_H__2CC80B1E_8D5D_45E3_A9D8_9086DDF68BB5__INCLUDED */ 1.9.12~dfsg/dbus/controller_internal.h0000644000000000000000000001307213214314510016530 0ustar rootroot/* -*- Mode: C ; c-basic-offset: 4 -*- */ /* Copyright (C) 2007,2008,2011 Nedko Arnaudov Copyright (C) 2007-2008 Juuso Alasuutari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef CONTROLLER_INTERNAL_H__04D54D51_3D79_49A2_A1DA_F8587E9E7F42__INCLUDED #define CONTROLLER_INTERNAL_H__04D54D51_3D79_49A2_A1DA_F8587E9E7F42__INCLUDED #include #include "jslist.h" #include "jack/control.h" #include "jack/jack.h" #include "jack/session.h" #include "jackdbus.h" #include "list.h" #include "params.h" struct jack_controller_slave_driver { struct list_head siblings; char * name; jackctl_driver_t * handle; bool loaded; }; struct jack_session_pending_command { struct list_head siblings; DBusConnection * connection; DBusMessage * message; jack_session_event_type_t type; const char * target; const char * path; }; struct jack_controller { jackctl_server_t *server; jack_params_handle params; void *patchbay_context; bool started; jack_client_t *client; unsigned int xruns; struct list_head slave_drivers; bool slave_drivers_set; struct jack_parameter slave_drivers_vparam; union jackctl_parameter_value slave_drivers_vparam_value; struct jack_dbus_object_descriptor dbus_descriptor; pthread_mutex_t lock; struct list_head session_pending_commands; long pending_save; /* uptime seconds */ }; #define DEFAULT_DRIVER "dummy" #define JACK_CONF_HEADER_TEXT \ "JACK settings, as persisted by D-Bus object.\n" \ "You probably don't want to edit this because\n" \ "it will be overwritten next time jackdbus saves.\n" void jack_controller_pending_save( struct jack_controller *controller_ptr); bool jack_controller_start_server( struct jack_controller *controller_ptr, void *dbus_call_context_ptr); bool jack_controller_stop_server( struct jack_controller *controller_ptr, void *dbus_call_context_ptr); bool jack_controller_switch_master( struct jack_controller *controller_ptr, void *dbus_call_context_ptr); bool jack_controller_add_slave_driver( struct jack_controller *controller_ptr, const char * driver_name); bool jack_controller_remove_slave_driver( struct jack_controller *controller_ptr, const char * driver_name); bool jack_controller_select_driver( struct jack_controller *controller_ptr, const char * driver_name); bool jack_controller_load_internal( struct jack_controller *controller_ptr, const char * internal_name); bool jack_controller_unload_internal( struct jack_controller *controller_ptr, const char * internal_name); void jack_controller_deserialize_parameter_value( struct jack_controller *controller_ptr, const char * const * address, const char * value); void jack_controller_serialize_parameter_value( const struct jack_parameter * param_ptr, char * value_buffer); bool jack_controller_patchbay_init( struct jack_controller *controller_ptr); void jack_controller_patchbay_uninit( struct jack_controller *controller_ptr); void * jack_controller_patchbay_client_appeared_callback( void * server_context, uint64_t client_id, const char *client_name); void jack_controller_patchbay_client_disappeared_callback( void *server_context, uint64_t client_id, void *client_context); void * jack_controller_patchbay_port_appeared_callback( void *server_context, uint64_t client_id, void *client_context, uint64_t port_id, const char *port_name, uint32_t port_flags, uint32_t port_type); void jack_controller_patchbay_port_disappeared_callback( void *server_context, uint64_t client_id, void *client_context, uint64_t port_id, void *port_context); void * jack_controller_patchbay_ports_connected_callback( void *server_context, uint64_t client1_id, void *client1_context, uint64_t port1_id, void *port1_context, uint64_t client2_id, void *client2_context, uint64_t port2_id, void *port2_context, uint64_t connection_id); void jack_controller_patchbay_ports_disconnected_callback( void *server_context, uint64_t client1_id, void *client1_context, uint64_t port1_id, void *port1_context, uint64_t client2_id, void *client2_context, uint64_t port2_id, void *port2_context, uint64_t connection_id, void *connection_context); extern struct jack_dbus_interface_descriptor g_jack_controller_iface_introspectable; extern struct jack_dbus_interface_descriptor g_jack_controller_iface_control; extern struct jack_dbus_interface_descriptor g_jack_controller_iface_configure; extern struct jack_dbus_interface_descriptor g_jack_controller_iface_patchbay; extern struct jack_dbus_interface_descriptor g_jack_controller_iface_session_manager; extern struct jack_dbus_interface_descriptor g_jack_controller_iface_transport; #endif /* #ifndef CONTROLLER_INTERNAL_H__04D54D51_3D79_49A2_A1DA_F8587E9E7F42__INCLUDED */ 1.9.12~dfsg/dbus/audio_reserve.h0000644000000000000000000000220213214314510015276 0ustar rootroot/* Copyright (C) 2009 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __audio_reserve__ #define __audio_reserve__ #include "JackCompilerDeps.h" #include #ifdef __cplusplus extern "C" { #endif SERVER_EXPORT int audio_reservation_init(); SERVER_EXPORT int audio_reservation_finish(); SERVER_EXPORT bool audio_acquire(const char * device_name); SERVER_EXPORT void audio_release(const char * device_name); SERVER_EXPORT void audio_reserve_loop(); #ifdef __cplusplus } /* extern "C" */ #endif #endif 1.9.12~dfsg/dbus/list.h0000644000000000000000000006716013214314510013433 0ustar rootroot/* -*- Mode: C ; c-basic-offset: 2 -*- */ /***************************************************************************** * * Linux kernel header adapted for user-mode * The 2.6.17-rt1 version was used. * * Original copyright holders of this code are unknown, they were not * mentioned in the original file. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *****************************************************************************/ #ifndef _LINUX_LIST_H #define _LINUX_LIST_H #include #if !defined(offsetof) #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif /** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #define prefetch(x) (x = x) /* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */ #define LIST_POISON1 ((void *) 0x00100100) #define LIST_POISON2 ((void *) 0x00200200) /* * Simple doubly linked list implementation. * * Some of the internal functions ("__xxx") are useful when * manipulating whole lists rather than single entries, as * sometimes we already know the next/prev entries and we can * generate better code by using them directly rather than * using the generic single-entry routines. */ struct list_head { struct list_head *next, *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; } /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; new->prev = prev; prev->next = new; } /** * list_add - add a new entry * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */ static inline void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } /** * list_add_tail - add a new entry * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. */ static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_add_rcu(struct list_head * new, struct list_head * prev, struct list_head * next) { new->next = next; new->prev = prev; // smp_wmb(); next->prev = new; prev->next = new; } /** * list_add_rcu - add a new entry to rcu-protected list * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as list_add_rcu() * or list_del_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * list_for_each_entry_rcu(). */ static inline void list_add_rcu(struct list_head *new, struct list_head *head) { __list_add_rcu(new, head, head->next); } /** * list_add_tail_rcu - add a new entry to rcu-protected list * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as list_add_tail_rcu() * or list_del_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * list_for_each_entry_rcu(). */ static inline void list_add_tail_rcu(struct list_head *new, struct list_head *head) { __list_add_rcu(new, head->prev, head); } /* * Delete a list entry by making the prev/next entries * point to each other. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; } /** * list_del - deletes entry from list. * @entry: the element to delete from the list. * Note: list_empty on entry does not return true after this, the entry is * in an undefined state. */ static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } /** * list_del_rcu - deletes entry from list without re-initialization * @entry: the element to delete from the list. * * Note: list_empty on entry does not return true after this, * the entry is in an undefined state. It is useful for RCU based * lockfree traversal. * * In particular, it means that we can not poison the forward * pointers that may still be used for walking the list. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as list_del_rcu() * or list_add_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * list_for_each_entry_rcu(). * * Note that the caller is not permitted to immediately free * the newly deleted entry. Instead, either synchronize_rcu() * or call_rcu() must be used to defer freeing until an RCU * grace period has elapsed. */ static inline void list_del_rcu(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->prev = LIST_POISON2; } /* * list_replace_rcu - replace old entry by new one * @old : the element to be replaced * @new : the new element to insert * * The old entry will be replaced with the new entry atomically. */ static inline void list_replace_rcu(struct list_head *old, struct list_head *new) { new->next = old->next; new->prev = old->prev; // smp_wmb(); new->next->prev = new; new->prev->next = new; old->prev = LIST_POISON2; } /** * list_del_init - deletes entry from list and reinitialize it. * @entry: the element to delete from the list. */ static inline void list_del_init(struct list_head *entry) { __list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry); } /** * list_move - delete from one list and add as another's head * @list: the entry to move * @head: the head that will precede our entry */ static inline void list_move(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add(list, head); } /** * list_move_tail - delete from one list and add as another's tail * @list: the entry to move * @head: the head that will follow our entry */ static inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add_tail(list, head); } /** * list_empty - tests whether a list is empty * @head: the list to test. */ static inline int list_empty(const struct list_head *head) { return head->next == head; } /** * list_empty_careful - tests whether a list is * empty _and_ checks that no other CPU might be * in the process of still modifying either member * * NOTE: using list_empty_careful() without synchronization * can only be safe if the only activity that can happen * to the list entry is list_del_init(). Eg. it cannot be used * if another CPU could re-list_add() it. * * @head: the list to test. */ static inline int list_empty_careful(const struct list_head *head) { struct list_head *next = head->next; return (next == head) && (next == head->prev); } static inline void __list_splice(struct list_head *list, struct list_head *head) { struct list_head *first = list->next; struct list_head *last = list->prev; struct list_head *at = head->next; first->prev = head; head->next = first; last->next = at; at->prev = last; } /** * list_splice - join two lists * @list: the new list to add. * @head: the place to add it in the first list. */ static inline void list_splice(struct list_head *list, struct list_head *head) { if (!list_empty(list)) __list_splice(list, head); } /** * list_splice_init - join two lists and reinitialise the emptied list. * @list: the new list to add. * @head: the place to add it in the first list. * * The list at @list is reinitialised */ static inline void list_splice_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head); INIT_LIST_HEAD(list); } } /** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) /** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. */ #define list_for_each(pos, head) \ for (pos = (head)->next; prefetch(pos->next), pos != (head); \ pos = pos->next) /** * __list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. * * This variant differs from list_for_each() in that it's the * simplest possible list iteration code, no prefetching is done. * Use this for code that knows the list to be very short (empty * or 1 entry) most of the time. */ #define __list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) /** * list_for_each_prev - iterate over a list backwards * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. */ #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ pos = pos->prev) /** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop counter. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) /** * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop counter. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_entry_reverse - iterate backwards over list of given type. * @pos: the type * to use as a loop counter. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_reverse(pos, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member); \ prefetch(pos->member.prev), &pos->member != (head); \ pos = list_entry(pos->member.prev, typeof(*pos), member)) /** * list_prepare_entry - prepare a pos entry for use as a start point in * list_for_each_entry_continue * @pos: the type * to use as a start point * @head: the head of the list * @member: the name of the list_struct within the struct. */ #define list_prepare_entry(pos, head, member) \ ((pos) ? : list_entry(head, typeof(*pos), member)) /** * list_for_each_entry_continue - iterate over list of given type * continuing after existing point * @pos: the type * to use as a loop counter. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_continue(pos, head, member) \ for (pos = list_entry(pos->member.next, typeof(*pos), member); \ prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_entry_from - iterate over list of given type * continuing from existing point * @pos: the type * to use as a loop counter. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_from(pos, head, member) \ for (; prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @pos: the type * to use as a loop counter. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /** * list_for_each_entry_safe_continue - iterate over list of given type * continuing after existing point safe against removal of list entry * @pos: the type * to use as a loop counter. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_safe_continue(pos, n, head, member) \ for (pos = list_entry(pos->member.next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /** * list_for_each_entry_safe_from - iterate over list of given type * from existing point safe against removal of list entry * @pos: the type * to use as a loop counter. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_safe_from(pos, n, head, member) \ for (n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /** * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against * removal of list entry * @pos: the type * to use as a loop counter. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_safe_reverse(pos, n, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member), \ n = list_entry(pos->member.prev, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.prev, typeof(*n), member)) /** * list_for_each_rcu - iterate over an rcu-protected list * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. * * This list-traversal primitive may safely run concurrently with * the _rcu list-mutation primitives such as list_add_rcu() * as long as the traversal is guarded by rcu_read_lock(). */ #define list_for_each_rcu(pos, head) \ for (pos = (head)->next; \ prefetch(rcu_dereference(pos)->next), pos != (head); \ pos = pos->next) #define __list_for_each_rcu(pos, head) \ for (pos = (head)->next; \ rcu_dereference(pos) != (head); \ pos = pos->next) /** * list_for_each_safe_rcu - iterate over an rcu-protected list safe * against removal of list entry * @pos: the &struct list_head to use as a loop counter. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. * * This list-traversal primitive may safely run concurrently with * the _rcu list-mutation primitives such as list_add_rcu() * as long as the traversal is guarded by rcu_read_lock(). */ #define list_for_each_safe_rcu(pos, n, head) \ for (pos = (head)->next; \ n = rcu_dereference(pos)->next, pos != (head); \ pos = n) /** * list_for_each_entry_rcu - iterate over rcu list of given type * @pos: the type * to use as a loop counter. * @head: the head for your list. * @member: the name of the list_struct within the struct. * * This list-traversal primitive may safely run concurrently with * the _rcu list-mutation primitives such as list_add_rcu() * as long as the traversal is guarded by rcu_read_lock(). */ #define list_for_each_entry_rcu(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ prefetch(rcu_dereference(pos)->member.next), \ &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_continue_rcu - iterate over an rcu-protected list * continuing after existing point. * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. * * This list-traversal primitive may safely run concurrently with * the _rcu list-mutation primitives such as list_add_rcu() * as long as the traversal is guarded by rcu_read_lock(). */ #define list_for_each_continue_rcu(pos, head) \ for ((pos) = (pos)->next; \ prefetch(rcu_dereference((pos))->next), (pos) != (head); \ (pos) = (pos)->next) /* * Double linked lists with a single pointer list head. * Mostly useful for hash tables where the two pointer list head is * too wasteful. * You lose the ability to access the tail in O(1). */ struct hlist_head { struct hlist_node *first; }; struct hlist_node { struct hlist_node *next, **pprev; }; #define HLIST_HEAD_INIT { .first = NULL } #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) static inline void INIT_HLIST_NODE(struct hlist_node *h) { h->next = NULL; h->pprev = NULL; } static inline int hlist_unhashed(const struct hlist_node *h) { return !h->pprev; } static inline int hlist_empty(const struct hlist_head *h) { return !h->first; } static inline void __hlist_del(struct hlist_node *n) { struct hlist_node *next = n->next; struct hlist_node **pprev = n->pprev; *pprev = next; if (next) next->pprev = pprev; } static inline void hlist_del(struct hlist_node *n) { __hlist_del(n); n->next = LIST_POISON1; n->pprev = LIST_POISON2; } /** * hlist_del_rcu - deletes entry from hash list without re-initialization * @n: the element to delete from the hash list. * * Note: list_unhashed() on entry does not return true after this, * the entry is in an undefined state. It is useful for RCU based * lockfree traversal. * * In particular, it means that we can not poison the forward * pointers that may still be used for walking the hash list. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as hlist_add_head_rcu() * or hlist_del_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * hlist_for_each_entry(). */ static inline void hlist_del_rcu(struct hlist_node *n) { __hlist_del(n); n->pprev = LIST_POISON2; } static inline void hlist_del_init(struct hlist_node *n) { if (!hlist_unhashed(n)) { __hlist_del(n); INIT_HLIST_NODE(n); } } /* * hlist_replace_rcu - replace old entry by new one * @old : the element to be replaced * @new : the new element to insert * * The old entry will be replaced with the new entry atomically. */ static inline void hlist_replace_rcu(struct hlist_node *old, struct hlist_node *new) { struct hlist_node *next = old->next; new->next = next; new->pprev = old->pprev; // smp_wmb(); if (next) new->next->pprev = &new->next; *new->pprev = new; old->pprev = LIST_POISON2; } static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; n->next = first; if (first) first->pprev = &n->next; h->first = n; n->pprev = &h->first; } /** * hlist_add_head_rcu - adds the specified element to the specified hlist, * while permitting racing traversals. * @n: the element to add to the hash list. * @h: the list to add to. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as hlist_add_head_rcu() * or hlist_del_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * hlist_for_each_entry_rcu(), used to prevent memory-consistency * problems on Alpha CPUs. Regardless of the type of CPU, the * list-traversal primitive must be guarded by rcu_read_lock(). */ static inline void hlist_add_head_rcu(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; n->next = first; n->pprev = &h->first; // smp_wmb(); if (first) first->pprev = &n->next; h->first = n; } /* next must be != NULL */ static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next) { n->pprev = next->pprev; n->next = next; next->pprev = &n->next; *(n->pprev) = n; } static inline void hlist_add_after(struct hlist_node *n, struct hlist_node *next) { next->next = n->next; n->next = next; next->pprev = &n->next; if(next->next) next->next->pprev = &next->next; } /** * hlist_add_before_rcu - adds the specified element to the specified hlist * before the specified node while permitting racing traversals. * @n: the new element to add to the hash list. * @next: the existing element to add the new element before. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as hlist_add_head_rcu() * or hlist_del_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * hlist_for_each_entry_rcu(), used to prevent memory-consistency * problems on Alpha CPUs. */ static inline void hlist_add_before_rcu(struct hlist_node *n, struct hlist_node *next) { n->pprev = next->pprev; n->next = next; // smp_wmb(); next->pprev = &n->next; *(n->pprev) = n; } /** * hlist_add_after_rcu - adds the specified element to the specified hlist * after the specified node while permitting racing traversals. * @prev: the existing element to add the new element after. * @n: the new element to add to the hash list. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as hlist_add_head_rcu() * or hlist_del_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * hlist_for_each_entry_rcu(), used to prevent memory-consistency * problems on Alpha CPUs. */ static inline void hlist_add_after_rcu(struct hlist_node *prev, struct hlist_node *n) { n->next = prev->next; n->pprev = &prev->next; // smp_wmb(); prev->next = n; if (n->next) n->next->pprev = &n->next; } #define hlist_entry(ptr, type, member) container_of(ptr,type,member) #define hlist_for_each(pos, head) \ for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ pos = pos->next) #define hlist_for_each_safe(pos, n, head) \ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ pos = n) /** * hlist_for_each_entry - iterate over list of given type * @tpos: the type * to use as a loop counter. * @pos: the &struct hlist_node to use as a loop counter. * @head: the head for your list. * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry(tpos, pos, head, member) \ for (pos = (head)->first; \ pos && ({ prefetch(pos->next); 1;}) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) /** * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point * @tpos: the type * to use as a loop counter. * @pos: the &struct hlist_node to use as a loop counter. * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry_continue(tpos, pos, member) \ for (pos = (pos)->next; \ pos && ({ prefetch(pos->next); 1;}) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) /** * hlist_for_each_entry_from - iterate over a hlist continuing from existing point * @tpos: the type * to use as a loop counter. * @pos: the &struct hlist_node to use as a loop counter. * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry_from(tpos, pos, member) \ for (; pos && ({ prefetch(pos->next); 1;}) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) /** * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @tpos: the type * to use as a loop counter. * @pos: the &struct hlist_node to use as a loop counter. * @n: another &struct hlist_node to use as temporary storage * @head: the head for your list. * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ for (pos = (head)->first; \ pos && ({ n = pos->next; 1; }) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = n) /** * hlist_for_each_entry_rcu - iterate over rcu list of given type * @tpos: the type * to use as a loop counter. * @pos: the &struct hlist_node to use as a loop counter. * @head: the head for your list. * @member: the name of the hlist_node within the struct. * * This list-traversal primitive may safely run concurrently with * the _rcu list-mutation primitives such as hlist_add_head_rcu() * as long as the traversal is guarded by rcu_read_lock(). */ #define hlist_for_each_entry_rcu(tpos, pos, head, member) \ for (pos = (head)->first; \ rcu_dereference(pos) && ({ prefetch(pos->next); 1;}) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) #endif 1.9.12~dfsg/dbus/reserve.c0000644000000000000000000003571013214314510014122 0ustar rootroot/*** Copyright 2009 Lennart Poettering Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ***/ #include #include #include #include #include #include #include #include "reserve.h" #include "jack/control.h" #define RESERVE_ERROR_NO_MEMORY "org.freedesktop.ReserveDevice1.Error.NoMemory" #define RESERVE_ERROR_PROTOCOL_VIOLATION "org.freedesktop.ReserveDevice1.Error.Protocol" #define RESERVE_ERROR_RELEASE_DENIED "org.freedesktop.ReserveDevice1.Error.ReleaseDenied" struct rd_device { int ref; char *device_name; char *application_name; char *application_device_name; char *service_name; char *object_path; int32_t priority; DBusConnection *connection; int owning:1; int registered:1; int filtering:1; int gave_up:1; rd_request_cb_t request_cb; void *userdata; }; #define SERVICE_PREFIX "org.freedesktop.ReserveDevice1." #define OBJECT_PREFIX "/org/freedesktop/ReserveDevice1/" static const char introspection[] = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "" " \n" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; static dbus_bool_t add_variant( DBusMessage *m, int type, const void *data) { DBusMessageIter iter, sub; char t[2]; t[0] = (char) type; t[1] = 0; dbus_message_iter_init_append(m, &iter); if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, t, &sub)) return FALSE; if (!dbus_message_iter_append_basic(&sub, type, data)) return FALSE; if (!dbus_message_iter_close_container(&iter, &sub)) return FALSE; return TRUE; } static DBusHandlerResult object_handler( DBusConnection *c, DBusMessage *m, void *userdata) { rd_device *d; DBusError error; DBusMessage *reply = NULL; dbus_error_init(&error); d = (rd_device*)userdata; assert(d->ref >= 1); if (dbus_message_is_method_call( m, "org.freedesktop.ReserveDevice1", "RequestRelease")) { int32_t priority; dbus_bool_t ret; if (!dbus_message_get_args( m, &error, DBUS_TYPE_INT32, &priority, DBUS_TYPE_INVALID)) goto invalid; ret = FALSE; if (priority > d->priority && d->request_cb) { d->ref++; if (d->request_cb(d, 0) > 0) { ret = TRUE; d->gave_up = 1; } rd_release(d); } if (!(reply = dbus_message_new_method_return(m))) goto oom; if (!dbus_message_append_args( reply, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID)) goto oom; if (!dbus_connection_send(c, reply, NULL)) goto oom; dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_method_call( m, "org.freedesktop.DBus.Properties", "Get")) { const char *interface, *property; if (!dbus_message_get_args( m, &error, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) goto invalid; if (strcmp(interface, "org.freedesktop.ReserveDevice1") == 0) { const char *empty = ""; if (strcmp(property, "ApplicationName") == 0 && d->application_name) { if (!(reply = dbus_message_new_method_return(m))) goto oom; if (!add_variant( reply, DBUS_TYPE_STRING, d->application_name ? (const char**) &d->application_name : &empty)) goto oom; } else if (strcmp(property, "ApplicationDeviceName") == 0) { if (!(reply = dbus_message_new_method_return(m))) goto oom; if (!add_variant( reply, DBUS_TYPE_STRING, d->application_device_name ? (const char**) &d->application_device_name : &empty)) goto oom; } else if (strcmp(property, "Priority") == 0) { if (!(reply = dbus_message_new_method_return(m))) goto oom; if (!add_variant( reply, DBUS_TYPE_INT32, &d->priority)) goto oom; } else { if (!(reply = dbus_message_new_error_printf( m, DBUS_ERROR_UNKNOWN_METHOD, "Unknown property %s", property))) goto oom; } if (!dbus_connection_send(c, reply, NULL)) goto oom; dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } } else if (dbus_message_is_method_call( m, "org.freedesktop.DBus.Introspectable", "Introspect")) { const char *i = introspection; if (!(reply = dbus_message_new_method_return(m))) goto oom; if (!dbus_message_append_args( reply, DBUS_TYPE_STRING, &i, DBUS_TYPE_INVALID)) goto oom; if (!dbus_connection_send(c, reply, NULL)) goto oom; dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; invalid: if (reply) dbus_message_unref(reply); if (!(reply = dbus_message_new_error( m, DBUS_ERROR_INVALID_ARGS, "Invalid arguments"))) goto oom; if (!dbus_connection_send(c, reply, NULL)) goto oom; dbus_message_unref(reply); dbus_error_free(&error); return DBUS_HANDLER_RESULT_HANDLED; oom: if (reply) dbus_message_unref(reply); dbus_error_free(&error); return DBUS_HANDLER_RESULT_NEED_MEMORY; } static DBusHandlerResult filter_handler( DBusConnection *c, DBusMessage *m, void *userdata) { DBusMessage *reply; rd_device *d; DBusError error; dbus_error_init(&error); d = (rd_device*)userdata; if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameLost")) { const char *name; if (!dbus_message_get_args( m, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) goto invalid; if (strcmp(name, d->service_name) == 0 && d->owning) { d->owning = 0; if (!d->gave_up) { d->ref++; if (d->request_cb) d->request_cb(d, 1); d->gave_up = 1; rd_release(d); } return DBUS_HANDLER_RESULT_HANDLED; } } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; invalid: if (!(reply = dbus_message_new_error( m, DBUS_ERROR_INVALID_ARGS, "Invalid arguments"))) goto oom; if (!dbus_connection_send(c, reply, NULL)) goto oom; dbus_message_unref(reply); dbus_error_free(&error); return DBUS_HANDLER_RESULT_HANDLED; oom: if (reply) dbus_message_unref(reply); dbus_error_free(&error); return DBUS_HANDLER_RESULT_NEED_MEMORY; } static DBusObjectPathVTable vtable; int rd_acquire( rd_device **_d, DBusConnection *connection, const char *device_name, const char *application_name, int32_t priority, rd_request_cb_t request_cb, DBusError *error) { rd_device *d = NULL; int r, k; DBusError _error; DBusMessage *m = NULL, *reply = NULL; dbus_bool_t good; vtable.message_function = object_handler; if (!error) { error = &_error; dbus_error_init(error); } if (!_d) { assert(0); r = -EINVAL; goto fail; } if (!connection) { assert(0); r = -EINVAL; goto fail; } if (!device_name) { assert(0); r = -EINVAL; goto fail; } if (!request_cb && priority != INT32_MAX) { assert(0); r = -EINVAL; goto fail; } if (!(d = (rd_device *)calloc(sizeof(rd_device), 1))) { dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for rd_device struct"); r = -ENOMEM; goto fail; } d->ref = 1; if (!(d->device_name = strdup(device_name))) { dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot duplicate device name string"); r = -ENOMEM; goto fail; } if (!(d->application_name = strdup(application_name))) { dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot duplicate application name string"); r = -ENOMEM; goto fail; } d->priority = priority; d->connection = dbus_connection_ref(connection); d->request_cb = request_cb; if (!(d->service_name = (char*)malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) { dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for service name string"); r = -ENOMEM; goto fail; } sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name); if (!(d->object_path = (char*)malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) { dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for object path string"); r = -ENOMEM; goto fail; } sprintf(d->object_path, OBJECT_PREFIX "%s", d->device_name); if ((k = dbus_bus_request_name( d->connection, d->service_name, DBUS_NAME_FLAG_DO_NOT_QUEUE| (priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0), error)) < 0) { jack_error("dbus_bus_request_name() failed. (1)"); r = -EIO; goto fail; } switch (k) { case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER: goto success; case DBUS_REQUEST_NAME_REPLY_EXISTS: break; case DBUS_REQUEST_NAME_REPLY_IN_QUEUE : /* DBUS_NAME_FLAG_DO_NOT_QUEUE was specified */ default: /* unknown reply returned */ jack_error("request name reply with unexpected value %d.", k); assert(0); r = -EIO; goto fail; } if (priority <= INT32_MIN) { r = -EBUSY; dbus_set_error(error, RESERVE_ERROR_RELEASE_DENIED, "Device reservation request with priority %"PRIi32" denied for \"%s\"", priority, device_name); goto fail; } if (!(m = dbus_message_new_method_call( d->service_name, d->object_path, "org.freedesktop.ReserveDevice1", "RequestRelease"))) { dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for RequestRelease method call"); r = -ENOMEM; goto fail; } if (!dbus_message_append_args( m, DBUS_TYPE_INT32, &d->priority, DBUS_TYPE_INVALID)) { dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot append args for RequestRelease method call"); r = -ENOMEM; goto fail; } if (!(reply = dbus_connection_send_with_reply_and_block( d->connection, m, 5000, /* 5s */ error))) { if (dbus_error_has_name(error, DBUS_ERROR_TIMED_OUT) || dbus_error_has_name(error, DBUS_ERROR_UNKNOWN_METHOD) || dbus_error_has_name(error, DBUS_ERROR_NO_REPLY)) { /* This must be treated as denied. */ jack_info("Device reservation request with priority %"PRIi32" denied for \"%s\": %s (%s)", priority, device_name, error->name, error->message); r = -EBUSY; goto fail; } jack_error("dbus_connection_send_with_reply_and_block(RequestRelease) failed."); r = -EIO; goto fail; } if (!dbus_message_get_args( reply, error, DBUS_TYPE_BOOLEAN, &good, DBUS_TYPE_INVALID)) { jack_error("RequestRelease() reply is invalid."); r = -EIO; goto fail; } if (!good) { dbus_set_error(error, RESERVE_ERROR_RELEASE_DENIED, "Device reservation request with priority %"PRIi32" denied for \"%s\" via RequestRelease()", priority, device_name); r = -EBUSY; goto fail; } if ((k = dbus_bus_request_name( d->connection, d->service_name, DBUS_NAME_FLAG_DO_NOT_QUEUE| (priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0)| DBUS_NAME_FLAG_REPLACE_EXISTING, error)) < 0) { jack_error("dbus_bus_request_name() failed. (2)"); r = -EIO; goto fail; } if (k != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { /* this is racy, another contender may have acquired the device */ dbus_set_error(error, RESERVE_ERROR_PROTOCOL_VIOLATION, "request name reply is not DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER but %d.", k); r = -EIO; goto fail; } success: d->owning = 1; if (!(dbus_connection_try_register_object_path( d->connection, d->object_path, &vtable, d, error))) { jack_error("cannot register object path \"%s\": %s", d->object_path, error->message); r = -ENOMEM; goto fail; } d->registered = 1; if (!dbus_connection_add_filter( d->connection, filter_handler, d, NULL)) { dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot add filter"); r = -ENOMEM; goto fail; } d->filtering = 1; *_d = d; return 0; fail: if (m) dbus_message_unref(m); if (reply) dbus_message_unref(reply); if (&_error == error) dbus_error_free(&_error); if (d) rd_release(d); return r; } void rd_release( rd_device *d) { if (!d) return; assert(d->ref > 0); if (--d->ref) return; if (d->filtering) dbus_connection_remove_filter( d->connection, filter_handler, d); if (d->registered) dbus_connection_unregister_object_path( d->connection, d->object_path); if (d->owning) { DBusError error; dbus_error_init(&error); dbus_bus_release_name( d->connection, d->service_name, &error); dbus_error_free(&error); } free(d->device_name); free(d->application_name); free(d->application_device_name); free(d->service_name); free(d->object_path); if (d->connection) dbus_connection_unref(d->connection); free(d); } int rd_set_application_device_name(rd_device *d, const char *n) { char *t; if (!d) return -EINVAL; assert(d->ref > 0); if (!(t = strdup(n))) return -ENOMEM; free(d->application_device_name); d->application_device_name = t; return 0; } void rd_set_userdata(rd_device *d, void *userdata) { if (!d) return; assert(d->ref > 0); d->userdata = userdata; } void* rd_get_userdata(rd_device *d) { if (!d) return NULL; assert(d->ref > 0); return d->userdata; } 1.9.12~dfsg/dbus/xml_write_raw.c0000644000000000000000000001736313214314510015336 0ustar rootroot/* -*- Mode: C ; c-basic-offset: 4 -*- */ /* Copyright (C) 2007,2008 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #if defined(HAVE_CONFIG_H) #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "controller_internal.h" #include "jackdbus.h" bool jack_controller_settings_write_string(int fd, const char * string, void *dbus_call_context_ptr) { size_t len; len = strlen(string); if (write(fd, string, len) != len) { jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "write() failed to write config file."); return false; } return true; } struct save_context { void * call; int fd; const char * indent; jack_params_handle params; const char * address[PARAM_ADDRESS_SIZE]; const char * str; }; #define ctx_ptr ((struct save_context *)context) #define fd (ctx_ptr->fd) static bool jack_controller_serialize_parameter(void * context, const struct jack_parameter * param_ptr) { char value[JACK_PARAM_STRING_MAX + 1]; if (!param_ptr->vtable.is_set(param_ptr->obj)) { return true; } jack_controller_serialize_parameter_value(param_ptr, value); return jack_controller_settings_write_string(fd, ctx_ptr->indent, ctx_ptr->call) && jack_controller_settings_write_string(fd, "\n", ctx_ptr->call); } bool serialize_modules(void * context, const char * name) { ctx_ptr->indent = " "; ctx_ptr->address[1] = name; ctx_ptr->address[2] = NULL; return jack_controller_settings_write_string(fd, " <", ctx_ptr->call) && jack_controller_settings_write_string(fd, ctx_ptr->str, ctx_ptr->call) && jack_controller_settings_write_string(fd, " name=\"", ctx_ptr->call) && jack_controller_settings_write_string(fd, name, ctx_ptr->call) && jack_controller_settings_write_string(fd, "\">\n", ctx_ptr->call) && jack_params_iterate_params(ctx_ptr->params, ctx_ptr->address, jack_controller_serialize_parameter, ctx_ptr) && jack_controller_settings_write_string(fd, " call) && jack_controller_settings_write_string(fd, ctx_ptr->str, ctx_ptr->call) && jack_controller_settings_write_string(fd, ">\n", ctx_ptr->call); } #undef fd #undef ctx_ptr bool jack_controller_settings_save( struct jack_controller * controller_ptr, void *dbus_call_context_ptr) { char *filename; size_t conf_len; int fd; bool ret; time_t timestamp; char timestamp_str[26]; struct save_context context; const char * modules[] = {"driver", "internal", NULL}; char buffer[100]; unsigned int i; time(×tamp); ctime_r(×tamp, timestamp_str); timestamp_str[24] = 0; ret = false; conf_len = strlen(JACKDBUS_CONF); filename = malloc(g_jackdbus_config_dir_len + conf_len + 1); if (filename == NULL) { jack_error("Out of memory."); goto exit; } memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len); memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len); filename[g_jackdbus_config_dir_len + conf_len] = 0; jack_info("Saving settings to \"%s\" ...", filename); fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd == -1) { jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno)); goto exit_free_filename; } context.fd = fd; context.call = dbus_call_context_ptr; if (!jack_controller_settings_write_string(fd, "\n", dbus_call_context_ptr)) { goto exit_close; } if (!jack_controller_settings_write_string(fd, "\n", dbus_call_context_ptr)) { goto exit_close; } if (!jack_controller_settings_write_string(fd, "\n", dbus_call_context_ptr)) { goto exit_close; } if (!jack_controller_settings_write_string(fd, "\n", dbus_call_context_ptr)) { goto exit_close; } /* engine */ if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) { goto exit_close; } context.indent = " "; context.address[0] = PTNODE_ENGINE; context.address[1] = NULL; if (!jack_params_iterate_params(controller_ptr->params, context.address, jack_controller_serialize_parameter, &context)) { goto exit_close; } if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) { goto exit_close; } for (i = 0; modules[i] != NULL; i++) { if (!jack_controller_settings_write_string(fd, " <", dbus_call_context_ptr)) { goto exit_close; } if (!jack_controller_settings_write_string(fd, modules[i], dbus_call_context_ptr)) { goto exit_close; } if (!jack_controller_settings_write_string(fd, "s>\n", dbus_call_context_ptr)) { goto exit_close; } context.indent = " "; context.params = controller_ptr->params; context.str = modules[i]; strcpy(buffer, modules[i]); strcat(buffer, "s"); context.address[0] = buffer; context.address[1] = NULL; if (!jack_params_iterate_container(controller_ptr->params, context.address, serialize_modules, &context)) { goto exit_close; } if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) { goto exit_close; } } if (!jack_controller_settings_write_string(fd, "\n", dbus_call_context_ptr)) { goto exit_close; } ret = true; exit_close: close(fd); exit_free_filename: free(filename); exit: return ret; } void jack_controller_settings_save_auto( struct jack_controller * controller_ptr) { jack_controller_settings_save(controller_ptr, NULL); } 1.9.12~dfsg/dbus/xml_expat.c0000644000000000000000000002034113214314510014442 0ustar rootroot/* -*- Mode: C ; c-basic-offset: 4 -*- */ /* Copyright (C) 2007,2008,2011 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #if defined(HAVE_CONFIG_H) #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "controller_internal.h" #include "jackdbus.h" bool jack_controller_settings_init() { return true; } void jack_controller_settings_uninit() { } struct parse_context { struct jack_controller *controller_ptr; XML_Bool error; bool option_value_capture; char option[JACK_PARAM_STRING_MAX+1]; int option_used; const char * address[PARAM_ADDRESS_SIZE]; int address_index; char * container; char *name; }; #define context_ptr ((struct parse_context *)data) void jack_controller_settings_callback_chrdata(void *data, const XML_Char *s, int len) { if (context_ptr->error) { return; } if (context_ptr->option_value_capture) { if (context_ptr->option_used + len >= JACK_PARAM_STRING_MAX) { jack_error("xml parse max char data length reached"); context_ptr->error = XML_TRUE; return; } memcpy(context_ptr->option + context_ptr->option_used, s, len); context_ptr->option_used += len; } } void jack_controller_settings_callback_elstart(void *data, const char *el, const char **attr) { if (context_ptr->error) { return; } if (context_ptr->address_index >= PARAM_ADDRESS_SIZE) { assert(context_ptr->address_index == PARAM_ADDRESS_SIZE); jack_error("xml param address max depth reached"); context_ptr->error = XML_TRUE; return; } //jack_info("<%s>", el); if (strcmp(el, "jack") == 0) { return; } if (strcmp(el, PTNODE_ENGINE) == 0) { context_ptr->address[context_ptr->address_index++] = PTNODE_ENGINE; return; } if (strcmp(el, PTNODE_DRIVERS) == 0) { context_ptr->address[context_ptr->address_index++] = PTNODE_DRIVERS; return; } if (strcmp(el, PTNODE_INTERNALS) == 0) { context_ptr->address[context_ptr->address_index++] = PTNODE_INTERNALS; return; } if (strcmp(el, "driver") == 0 || strcmp(el, "internal") == 0) { if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) { jack_error("<%s> XML element must contain exactly one attribute, named \"name\"", el); context_ptr->error = XML_TRUE; return; } context_ptr->container = strdup(attr[1]); if (context_ptr->container == NULL) { jack_error("strdup() failed"); context_ptr->error = XML_TRUE; return; } context_ptr->address[context_ptr->address_index++] = context_ptr->container; return; } if (strcmp(el, "option") == 0) { if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) { jack_error("Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES