| 
							- /*
 - Copyright (C) 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.
 - 
 - */
 - 
 - #ifdef WIN32
 - #pragma warning (disable : 4786)
 - #endif
 - 
 - #include <stdio.h>
 - #include <string.h>
 - #include <assert.h>
 - #include <process.h>
 - #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.
 - 
 -  */
 - 
 - //------------------------------------------------------------------------------------------
 - // 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"
 - #include "psapi.h"
 - 
 - using namespace std;
 - 
 - // 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,"JackRouter.dll","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,"JackRouter.dll","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<pair<string, string> > JackRouter::fConnections;
 - bool JackRouter::fFirstActivate = true;
 - 
 - //------------------------------------------------------------------------------------------
 - //------------------------------------------------------------------------------------------
 - 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;
 - 	fActive = false;
 - 	fStarted = false;
 - 	fTimeInfoMode = false;
 - 	fTcRead = false;
 - 	fClient = NULL;
 - 	fAutoConnectIn = true;
 - 	fAutoConnectOut = true;
 - 
 - 	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;
 - 	}
 - 	fCallbacks = 0;
 - 	fActiveInputs = fActiveOutputs = 0;
 - 	fToggle = 0;
 - 	fBufferSize = 512;
 - 	fSampleRate = 44100;
 - 	printf("Constructor\n");
 - 
 - 	// Use "jackrouter.ini" parameters if available
 - 	HMODULE handle = LoadLibrary("JackRouter.dll");
 - 
 - 	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());
 - 
 - 		FreeLibrary(handle);
 - 
 - 	} else {
 - 		printf("LoadLibrary error\n");
 - 	}
 - }
 - 
 - //------------------------------------------------------------------------------------------
 - JackRouter::~JackRouter()
 - {
 - 	stop ();
 - 	disposeBuffers ();
 - 	printf("Destructor\n");
 - 	jack_client_close(fClient);
 - }
 - 
 - //------------------------------------------------------------------------------------------
 - #include <windows.h>
 - #include <stdio.h>
 - #include <tchar.h>
 - #include "psapi.h"
 - 
 - 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 float ClipFloat(float sample)
 - {
 -      return (sample < -1.0f) ? -1.0f : (sample > 1.0f) ? 1.0f : sample;
 - }
 - 
 - //------------------------------------------------------------------------------------------
 - void JackRouter::shutdown(void* arg)
 - {
 - 	JackRouter* driver = (JackRouter*)arg;
 - 	/*
 - 	//exit(1);
 - 	char errstr[128];
 - 
 - 	memset(errstr,0,128);
 - 	sprintf(errstr,"JACK server has quitted");
 - 	MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK);
 - 	*/
 - }
 - 
 - //------------------------------------------------------------------------------------------
 - int JackRouter::process(jack_nframes_t nframes, void* arg)
 - {
 - 	JackRouter* driver = (JackRouter*)arg;
 - 	int i,j;
 - 	int pos = (driver->fToggle) ? 0 : driver->fBufferSize ;	
 - 	
 - 	for (i = 0; i < driver->fActiveInputs; i++) {	
 - 		
 - #ifdef LONG_SAMPLE		
 - 		float* buffer = (float*)jack_port_get_buffer(driver->fInputPorts[i], nframes);
 - 		long* in = driver->fInputBuffers[i] + pos;
 - 		for (j = 0; j < nframes; j++) {
 - 			in[j] = buffer[j] * float(0x7fffffff);
 - 		}
 - #else
 - 		memcpy(driver->fInputBuffers[i] + pos,
 - 				jack_port_get_buffer(driver->fInputPorts[i], nframes),
 - 				nframes * sizeof(float));
 - #endif
 - 
 - 	}	
 - 
 - 	driver->bufferSwitch();
 - 
 - 	for (i = 0; i < driver->fActiveOutputs; i++) {
 - 
 - #ifdef LONG_SAMPLE
 - 		float* buffer = (float*)jack_port_get_buffer(driver->fOutputPorts[i], nframes);
 - 		long* out = driver->fOutputBuffers[i] + pos;
 - 		float gain = 1.f/float(0x7fffffff);
 - 		for (j = 0; j < nframes; j++) {
 - 			buffer[j] = out[j] * gain;
 - 		}
 - #else
 - 		memcpy(jack_port_get_buffer(driver->fOutputPorts[i], nframes),
 - 				driver->fOutputBuffers[i] + pos,
 - 				nframes * sizeof(float));
 - #endif
 - 	}
 - 	
 - 	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];
 - 	sysRef = sysRef;
 - 
 - 	if (fActive)
 - 		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);
 - 	}
 - 
 - 	if (fClient) {
 - 		printf("Error: jack client still present...\n");
 - 		return true;
 - 	}
 - 		
 - 	fClient = jack_client_open(name, JackNullOption, 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, process, this);
 - 	jack_on_shutdown(fClient, shutdown, 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
 - 
 - 	printf("Init ASIO Jack\n");
 - 	fActive = true;
 - 	return true;
 - }
 - 
 - //------------------------------------------------------------------------------------------
 - ASIOError JackRouter::start()
 - {
 - 	if (fCallbacks) {
 - 		fSamplePosition = 0;
 - 		fTheSystemTime.lo = fTheSystemTime.hi = 0;
 - 		fToggle = 0;
 - 		fStarted = true;
 - 		printf("Start ASIO Jack\n");
 - 	
 - 		if (jack_activate(fClient) == 0) {
 - 
 - 			if (fFirstActivate) {
 - 				AutoConnect();
 - 				fFirstActivate = false;
 - 			} else {
 - 				RestoreConnections();
 - 			}
 - 
 - 			return ASE_OK;
 - 
 - 		} else {
 - 			return ASE_NotPresent;
 - 		}		
 - 	}
 - 	
 - 	return ASE_NotPresent;
 - }
 - 
 - //------------------------------------------------------------------------------------------
 - ASIOError JackRouter::stop()
 - {
 - 	fStarted = false;
 - 	printf("Stop ASIO Jack\n");
 - 	SaveConnections();
 - 	jack_deactivate(fClient);
 - 	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;		// allow 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;
 - #ifdef LONG_SAMPLE
 - 	info->type = ASIOSTInt32LSB;
 - #else
 - 	info->type = ASIOSTFloat32LSB;
 - #endif
 - 
 - 	info->channelGroup = 0;
 - 	info->isActive = ASIOFalse;
 - 	long i;
 - 	char buf[32];
 - 
 - 	if (info->isInput) {
 - 		for (i = 0; i < fActiveInputs; i++) {		
 - 			if (fInMap[i] == info->channel) { 
 - 				info->isActive = ASIOTrue;
 - 				//_snprintf(buf, sizeof(buf) - 1, "Jack::In%d ", info->channel);
 - 				//strcpy(info->name, buf);
 - 				//strcpy(info->name, jack_port_name(fInputPorts[i]));
 - 				break;
 - 			}
 - 		}
 - 		_snprintf(buf, sizeof(buf) - 1, "In%d ", info->channel);
 - 		strcpy(info->name, buf);
 - 	} else {
 - 		for (i = 0; i < fActiveOutputs; i++) {	
 - 			if (fOutMap[i] == info->channel) {  //NOT USED !!
 - 				info->isActive = ASIOTrue;
 - 				//_snprintf(buf, sizeof(buf) - 1, "Jack::Out%d ", info->channel);
 - 				//strcpy(info->name, buf);
 - 				//strcpy(info->name, jack_port_name(fOutputPorts[i]));
 - 				break;
 - 			}
 - 		}
 - 		_snprintf(buf, sizeof(buf) - 1, "Out%d ", info->channel);
 - 		strcpy(info->name, buf);
 - 	}
 - 	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;
 - 
 - 	for (i = 0; i < numChannels; i++, info++) {
 - 		if (info->isInput) {
 - 			if (info->channelNum < 0 || info->channelNum >= kNumInputs)
 - 				goto error;
 - 			fInMap[fActiveInputs] = info->channelNum;
 - 		#ifdef LONG_SAMPLE
 - 			fInputBuffers[fActiveInputs] = new long[fBufferSize * 2];	// double buffer
 - 		#else
 - 			fInputBuffers[fActiveInputs] = new float[fBufferSize * 2];	// double buffer
 - 		#endif
 - 			if (fInputBuffers[fActiveInputs]) {
 - 				info->buffers[0] = fInputBuffers[fActiveInputs];
 - 				info->buffers[1] = fInputBuffers[fActiveInputs] + fBufferSize;
 - 			} else {
 - 				info->buffers[0] = info->buffers[1] = 0;
 - 				notEnoughMem = true;
 - 			}
 - 			
 - 			_snprintf(buf, sizeof(buf) - 1, "in%d", fActiveInputs + 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 {	// output			
 - 			if (info->channelNum < 0 || info->channelNum >= kNumOutputs)
 - 				goto error;
 - 			fOutMap[fActiveOutputs] = info->channelNum;
 - 	
 - 		#ifdef LONG_SAMPLE
 - 			fOutputBuffers[fActiveOutputs] = new long[fBufferSize * 2];	// double buffer
 - 		#else
 - 			fOutputBuffers[fActiveOutputs] = new float[fBufferSize * 2];	// double buffer
 - 		#endif
 - 	
 - 			if (fOutputBuffers[fActiveOutputs]) {
 - 				info->buffers[0] = fOutputBuffers[fActiveOutputs];
 - 				info->buffers[1] = fOutputBuffers[fActiveOutputs] + fBufferSize;
 - 			} else {
 - 				info->buffers[0] = info->buffers[1] = 0;
 - 				notEnoughMem = true;
 - 			}
 - 			
 - 			_snprintf(buf, sizeof(buf) - 1, "out%d", fActiveOutputs + 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;	
 - 	}
 - 	
 - 	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 (fStarted && fCallbacks) {
 - 		getNanoSeconds(&fTheSystemTime);			// latch system time
 - 		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<pair<string, string> >::const_iterator it;
 - 
 -     for (it = fConnections.begin(); it != fConnections.end(); it++) {
 -         pair<string, string> connection = *it;
 -         jack_connect(fClient, connection.first.c_str(), connection.second.c_str());
 -     }
 - 
 -     fConnections.clear();
 - }
 - 
 - //------------------------------------------------------------------------------------------
 - void JackRouter::AutoConnect()
 - {
 - 	const char** ports;
 - 	
 - 	if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput)) == NULL) {
 - 		printf("Cannot find any physical capture ports\n");
 - 	} else {
 - 		if (fAutoConnectIn) {
 - 			for (int i = 0; i < fActiveInputs; i++) {
 - 				if (!ports[i]) {
 - 					printf("source port is null i = %ld\n", i);
 - 					break;
 - 				} else if (jack_connect(fClient, ports[i], jack_port_name(fInputPorts[i])) != 0) {
 - 					printf("Cannot connect input ports\n");
 - 				}
 - 			}
 - 		}
 - 		jack_free(ports); 
 - 	}
 - 	
 - 	if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput)) == NULL) {
 - 		printf("Cannot find any physical playback ports");
 - 	} else {
 - 		if (fAutoConnectOut) {
 - 			for (int i = 0; i < fActiveOutputs; i++) {
 - 				if (!ports[i]){
 - 					printf("destination port is null i = %ld\n", i);
 - 					break;
 - 				} else if (jack_connect(fClient, jack_port_name(fOutputPorts[i]), ports[i]) != 0) {
 - 					printf("Cannot connect output ports\n");
 - 				}
 - 			}
 - 		}
 - 		jack_free(ports); 
 - 	}
 - }
 - 
 
 
  |