Logo Search packages:      
Sourcecode: jackd2 version File versions  Download package

JackRouter.cpp

/*
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); 
      }
}


Generated by  Doxygen 1.6.0   Back to index