Browse Source

Cleanup, documentation.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2705 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.90
sletz 17 years ago
parent
commit
2280b77679
21 changed files with 837 additions and 776 deletions
  1. +1
    -0
      common/JackAudioAdapter.cpp
  2. +12
    -5
      common/JackAudioAdapter.h
  3. +116
    -111
      common/JackAudioAdapterInterface.h
  4. +1
    -0
      common/JackChannel.h
  5. +0
    -8
      common/JackClient.cpp
  6. +45
    -37
      common/JackException.h
  7. +30
    -26
      common/JackLibSampleRateResampler.h
  8. +1
    -1
      common/JackLockedEngine.h
  9. +4
    -0
      common/JackMessageBuffer.h
  10. +8
    -0
      common/JackMutex.h
  11. +5
    -0
      common/JackNotification.h
  12. +39
    -35
      common/JackResampler.h
  13. +5
    -1
      common/JackRestartThreadedDriver.h
  14. +1
    -2
      common/JackTools.cpp
  15. +14
    -6
      common/JackTools.h
  16. +4
    -0
      common/JackWaitThreadedDriver.h
  17. +1
    -3
      linux/alsa/JackAlsaAdapter.cpp
  18. +448
    -443
      linux/alsa/JackAlsaAdapter.h
  19. +77
    -73
      macosx/JackCoreAudioAdapter.h
  20. +25
    -20
      windows/JackPortAudioAdapter.h
  21. +0
    -5
      windows/getopt.h

+ 1
- 0
common/JackAudioAdapter.cpp View File

@@ -31,6 +31,7 @@ using namespace std;

namespace Jack
{

//static methods ***********************************************************
int JackAudioAdapter::Process(jack_nframes_t frames, void* arg)
{


+ 12
- 5
common/JackAudioAdapter.h View File

@@ -27,9 +27,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack
{

class JackAudioAdapter
{
/*!
\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);
@@ -50,14 +55,16 @@ namespace Jack
void Reset();

public:
JackAudioAdapter(jack_client_t* jack_client, JackAudioAdapterInterface* audio_io) :
fJackClient(jack_client), fAudioAdapter(audio_io)
{}
fJackClient(jack_client), fAudioAdapter(audio_io)
{}
~JackAudioAdapter();

int Open();
int Close();
};
};

}

#endif

+ 116
- 111
common/JackAudioAdapterInterface.h View File

@@ -33,123 +33,128 @@ namespace Jack

#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)
{}
struct Measure
{
int delta;
int time1;
int time2;
float r1;
float r2;
int pos1;
int pos2;
};

struct MeasureTable
{

void Write(int time1, int time2, float r1, float r2, int pos1, int pos2);
void Save();
};
Measure fTable[TABLE_MAX];
int fCount;

class JackAudioAdapterInterface
{
protected:
MeasureTable():fCount(0)
{}

void Write(int time1, int time2, float r1, float r2, int pos1, int pos2);
void Save();

};

#ifdef DEBUG
MeasureTable fTable;
#endif
/*!
\brief Base class for audio adapters.
*/

class JackAudioAdapterInterface
{

protected:

#ifdef DEBUG
MeasureTable fTable;
#endif
int fCaptureChannels;
int fPlaybackChannels;
int fCaptureChannels;
int fPlaybackChannels;
jack_nframes_t fBufferSize;
jack_nframes_t fSampleRate;
// DLL
JackAtomicDelayLockedLoop fProducerDLL;
JackAtomicDelayLockedLoop fConsumerDLL;
JackResampler** fCaptureRingBuffer;
JackResampler** fPlaybackRingBuffer;

bool fRunning;
public:
jack_nframes_t fBufferSize;
jack_nframes_t fSampleRate;
// DLL
JackAtomicDelayLockedLoop fProducerDLL;
JackAtomicDelayLockedLoop fConsumerDLL;
JackResampler** fCaptureRingBuffer;
JackResampler** fPlaybackRingBuffer;

bool fRunning;
public:
JackAudioAdapterInterface(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
:fBufferSize(buffer_size),
fSampleRate(sample_rate),
fProducerDLL(buffer_size, sample_rate),
fConsumerDLL(buffer_size, sample_rate),
fRunning(false)
{}
virtual ~JackAudioAdapterInterface()
{}
void SetRingBuffers(JackResampler** input, JackResampler** output)
{
fCaptureRingBuffer = input;
fPlaybackRingBuffer = output;
}
bool IsRunning() {return fRunning;}
virtual void Reset() {fRunning = false;}
void ResetRingBuffers();
virtual int Open();
virtual int Close();
JackAudioAdapterInterface(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
:fBufferSize(buffer_size),
fSampleRate(sample_rate),
fProducerDLL(buffer_size, sample_rate),
fConsumerDLL(buffer_size, sample_rate),
fRunning(false)
{}
virtual ~JackAudioAdapterInterface()
{}
void SetRingBuffers(JackResampler** input, JackResampler** output)
{
fCaptureRingBuffer = input;
fPlaybackRingBuffer = output;
}
bool IsRunning() {return fRunning;}
virtual void Reset() {fRunning = false;}
void ResetRingBuffers();
virtual int Open();
virtual int Close();
virtual int SetBufferSize(jack_nframes_t buffer_size)
{
fBufferSize = buffer_size;
fConsumerDLL.Init(fBufferSize, fSampleRate);
fProducerDLL.Init(fBufferSize, fSampleRate);
return 0;
}
virtual int SetSampleRate(jack_nframes_t sample_rate)
{
fSampleRate = sample_rate;
fConsumerDLL.Init(fBufferSize, fSampleRate);
// Producer (Audio) keeps the same SR
return 0;
}
virtual int SetAudioSampleRate(jack_nframes_t sample_rate)
{
fSampleRate = sample_rate;
// Consumer keeps the same SR
fProducerDLL.Init(fBufferSize, fSampleRate);
return 0;
}
virtual void SetCallbackTime(jack_time_t callback_usec)
{
fConsumerDLL.IncFrame(callback_usec);
}
void ResampleFactor(jack_nframes_t& frame1, jack_nframes_t& frame2);
int GetInputs()
{
return fCaptureChannels;
}
int GetOutputs()
{
return fPlaybackChannels;
}
virtual int SetBufferSize(jack_nframes_t buffer_size)
{
fBufferSize = buffer_size;
fConsumerDLL.Init(fBufferSize, fSampleRate);
fProducerDLL.Init(fBufferSize, fSampleRate);
return 0;
}
};
virtual int SetSampleRate(jack_nframes_t sample_rate)
{
fSampleRate = sample_rate;
fConsumerDLL.Init(fBufferSize, fSampleRate);
// Producer (Audio) keeps the same SR
return 0;
}
virtual int SetAudioSampleRate(jack_nframes_t sample_rate)
{
fSampleRate = sample_rate;
// Consumer keeps the same SR
fProducerDLL.Init(fBufferSize, fSampleRate);
return 0;
}
virtual void SetCallbackTime(jack_time_t callback_usec)
{
fConsumerDLL.IncFrame(callback_usec);
}
void ResampleFactor(jack_nframes_t& frame1, jack_nframes_t& frame2);
int GetInputs()
{
return fCaptureChannels;
}
int GetOutputs()
{
return fPlaybackChannels;
}
};

}

#endif

+ 1
- 0
common/JackChannel.h View File

@@ -33,6 +33,7 @@ class JackGraphManager;

namespace detail
{

/*!
\brief Inter process channel for server/client bidirectionnal communication : request and (receiving) notifications.
*/


+ 0
- 8
common/JackClient.cpp View File

@@ -399,14 +399,6 @@ jack_nframes_t JackClient::Wait(int status)
return GetEngineControl()->fBufferSize;
}

/*
jack_nframes_t JackClient::Wait(int status)
{
CycleSignal(status);
return CycleWait();
}
*/

jack_nframes_t JackClient::CycleWait()
{
if (!WaitSync())


+ 45
- 37
common/JackException.h View File

@@ -29,43 +29,51 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack
{

class 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()
{
std::string str = what();
if (str != "")
jack_info(str.c_str());
}
};

class EXPORT JackDriverException : public JackException {

public:

JackDriverException(const std::string& msg) : JackException(msg)
{}
JackDriverException(char* msg) : JackException(msg)
{}
JackDriverException(const char* msg) : JackException(msg)
{}
JackDriverException() : JackException("")
{}
};
/*!
\brief Exception base class.
*/

class 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()
{
std::string str = what();
if (str != "")
jack_info(str.c_str());
}
};

/*!
\brief Exception possibly thrown by drivers.
*/

class EXPORT JackDriverException : public JackException {

public:

JackDriverException(const std::string& msg) : JackException(msg)
{}
JackDriverException(char* msg) : JackException(msg)
{}
JackDriverException(const char* msg) : JackException(msg)
{}
JackDriverException() : JackException("")
{}
};

}



+ 30
- 26
common/JackLibSampleRateResampler.h View File

@@ -26,36 +26,40 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack
{

inline float Range(float min, float max, float val)
{
return (val < min) ? min : ((val > max) ? max : val);
}
inline float Range(float min, float max, float val)
{
return (val < min) ? min : ((val > max) ? max : val);
}
/*!
\brief Resampler using "libsamplerate" (http://www.mega-nerd.com/SRC/).
*/

class JackLibSampleRateResampler : public JackResampler
{
class JackLibSampleRateResampler : public JackResampler
{

private:
SRC_STATE* fResampler;
double fRatio;
public:
private:
JackLibSampleRateResampler();
virtual ~JackLibSampleRateResampler();
SRC_STATE* fResampler;
double fRatio;
public:
unsigned int ReadResample(float* buffer, unsigned int frames);
unsigned int WriteResample(float* buffer, unsigned int frames);
void SetRatio(unsigned int num, unsigned int denom)
{
JackResampler::SetRatio(num, denom);
fRatio = Range(0.25f, 4.0f, (double(num) / double(denom)));
}
JackLibSampleRateResampler();
virtual ~JackLibSampleRateResampler();
unsigned int ReadResample(float* buffer, unsigned int frames);
unsigned int WriteResample(float* buffer, unsigned int frames);
void SetRatio(unsigned int num, unsigned int denom)
{
JackResampler::SetRatio(num, denom);
fRatio = Range(0.25f, 4.0f, (double(num) / double(denom)));
}
void Reset();
};
void Reset();
};
}

#endif

+ 1
- 1
common/JackLockedEngine.h View File

@@ -27,7 +27,7 @@ namespace Jack
{

/*!
\brief Locked Engine.
\brief Locked Engine, access to methods is serialized using a mutex.
*/

class EXPORT JackLockedEngine : public JackLockAble


+ 4
- 0
common/JackMessageBuffer.h View File

@@ -49,6 +49,10 @@ struct JackMessage
char message[MB_BUFFERSIZE];
};

/*!
\brief Message buffer to be used from RT threads.
*/

class JackMessageBuffer : public JackRunnableInterface
{



+ 8
- 0
common/JackMutex.h View File

@@ -34,6 +34,10 @@
namespace Jack
{

/*!
\brief Mutex abstraction.
*/

class JackMutex
{

@@ -117,6 +121,10 @@ class JackMutex
#endif
};

/*!
\brief Base class for "lockable" objects.
*/

class JackLockAble
{



+ 5
- 0
common/JackNotification.h View File

@@ -22,6 +22,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

namespace Jack
{

/*!
\brief Notifications sent by the server for clients.
*/

enum NotificationType {
kAddClient = 0,
kRemoveClient = 1,


+ 39
- 35
common/JackResampler.h View File

@@ -26,45 +26,49 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack
{

#define DEFAULT_RB_SIZE 16384 * 2
#define DEFAULT_RB_SIZE 16384 * 2

class JackResampler
{
/*!
\brief Base class for Resampler.
*/

class JackResampler
{

protected:
jack_ringbuffer_t* fRingBuffer;
unsigned int fNum;
unsigned int fDenom;
public:
protected:
JackResampler();
virtual ~JackResampler();
jack_ringbuffer_t* fRingBuffer;
unsigned int fNum;
unsigned int fDenom;
public:
virtual void Reset();
JackResampler();
virtual ~JackResampler();
virtual void Reset();
virtual unsigned int ReadResample(float* buffer, unsigned int frames);
virtual unsigned int WriteResample(float* buffer, unsigned int frames);
virtual unsigned int Read(float* buffer, unsigned int frames);
virtual unsigned int Write(float* buffer, unsigned int frames);
virtual unsigned int ReadSpace();
virtual unsigned int WriteSpace();
virtual void SetRatio(unsigned int num, unsigned int denom)
{
fNum = num;
fDenom = denom;
}
virtual void GetRatio(unsigned int& num, unsigned int& denom)
{
num = fNum;
denom = fDenom;
}
};
virtual unsigned int ReadResample(float* buffer, unsigned int frames);
virtual unsigned int WriteResample(float* buffer, unsigned int frames);
virtual unsigned int Read(float* buffer, unsigned int frames);
virtual unsigned int Write(float* buffer, unsigned int frames);
virtual unsigned int ReadSpace();
virtual unsigned int WriteSpace();

virtual void SetRatio(unsigned int num, unsigned int denom)
{
fNum = num;
fDenom = denom;
}
virtual void GetRatio(unsigned int& num, unsigned int& denom)
{
num = fNum;
denom = fDenom;
}
};
}

#endif

+ 5
- 1
common/JackRestartThreadedDriver.h View File

@@ -19,13 +19,17 @@
*/

#ifndef __JackRestartThreadedDriver__
#define __JackRestartThreadedDriverr__
#define __JackRestartThreadedDriver__

#include "JackThreadedDriver.h"

namespace Jack
{

/*!
\brief Restart a driver after an exception is thrown.
*/

class EXPORT JackRestartThreadedDriver : public JackThreadedDriver
{
public:


+ 1
- 2
common/JackTools.cpp View File

@@ -275,8 +275,7 @@ namespace Jack {
}

JackArgParser::~JackArgParser()
{
}
{}

string JackArgParser::GetArgString()
{


+ 14
- 6
common/JackTools.h View File

@@ -43,9 +43,12 @@
namespace Jack
{

/*!
\brief Utility functions.
*/

struct EXPORT JackTools
{

static int GetPID();
static int GetUID();

@@ -55,26 +58,31 @@ struct EXPORT JackTools
static void CleanupFiles(const char* server_name);
static int GetTmpdir();
static void RewriteName(const char* name, char* new_name);

};

/*!
\brief Internal cient command line parser.
*/

class EXPORT JackArgParser
{
private:
std::string fArgString;
int fArgc;
std::vector<std::string> fArgv;

public:
JackArgParser(const char* arg);
~JackArgParser();
std::string GetArgString();
int GetNumArgv();
int GetArgc();
int GetArgv ( std::vector<std::string>& argv );
int GetArgv ( char** argv );
void DeleteArgv ( const char** argv );
int ParseParams ( jack_driver_desc_t* desc, JSList** param_list );
int GetArgv(std::vector<std::string>& argv);
int GetArgv(char** argv);
void DeleteArgv(const char** argv);
int ParseParams(jack_driver_desc_t* desc, JSList** param_list);
};

}


+ 4
- 0
common/JackWaitThreadedDriver.h View File

@@ -27,6 +27,10 @@
namespace Jack
{
/*!
\brief To be used as a wrapper of JackNetDriver.
*/

class EXPORT JackWaitThreadedDriver : public JackThreadedDriver
{
private:


+ 1
- 3
linux/alsa/JackAlsaAdapter.cpp View File

@@ -22,7 +22,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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(GetInputs(), GetOutputs(), buffer_size, sample_rate)
@@ -73,8 +72,7 @@ int JackAlsaAdapter::Open()
if (fAudioInterface.open() == 0) {
fAudioInterface.longinfo();
fThread.AcquireRealTime(85);
fThread.StartSync();
return 0;
return fThread.StartSync();
} else {
return -1;
}


+ 448
- 443
linux/alsa/JackAlsaAdapter.h View File

@@ -33,514 +33,519 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack
{

//inline void* aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb * size) + 15, sizeof(char))) + 15 & ~15); }
inline void* aligned_calloc(size_t nmemb, size_t size) { return (void*)calloc(nmemb, size); }
//inline void* aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb * size) + 15, sizeof(char))) + 15 & ~15); }
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;
#define max(x,y) (((x)>(y)) ? (x) : (y))
#define min(x,y) (((x)<(y)) ? (x) : (y))
unsigned int fSoftInputs;
unsigned int fSoftOutputs;
public:
AudioParam() :
fCardName("hw:0"),
fFrequency(44100),
fBuffering(512),
fSoftInputs(2),
fSoftOutputs(2)
{}
AudioParam(int input, int output, jack_nframes_t buffer_size, jack_nframes_t sample_rate) :
fCardName("hw:0"),
fFrequency(sample_rate),
fBuffering(buffer_size),
fSoftInputs(input),
fSoftOutputs(output)
{}
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; }
AudioParam& inputs(int n) { fSoftInputs = n; return *this; }
AudioParam& outputs(int n) { fSoftOutputs = n; return *this; }
};

/**
* An ALSA audio interface
*/
class AudioInterface : public AudioParam
{

#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); }
public:
snd_pcm_t* fOutputDevice;
snd_pcm_t* fInputDevice;
snd_pcm_hw_params_t* fInputParams;
snd_pcm_hw_params_t* fOutputParams;
snd_pcm_format_t fSampleFormat;
snd_pcm_access_t fSampleAccess;
unsigned int fCardInputs;
unsigned int fCardOutputs;
unsigned int fChanInputs;
unsigned int fChanOutputs;
// 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
float* fInputSoftChannels[256];
float* fOutputSoftChannels[256];

/**
* A convenient class to pass parameters to AudioInterface
*/
class AudioParam
public:
const char* cardName() { return fCardName; }
int frequency() { return fFrequency; }
int buffering() { return fBuffering; }
float** inputSoftChannels() { return fInputSoftChannels; }
float** outputSoftChannels() { return fOutputSoftChannels; }
AudioInterface(const AudioParam& ap = AudioParam()) : AudioParam(ap)
{
fInputDevice = 0;
fOutputDevice = 0;
fInputParams = 0;
fOutputParams = 0;
}

AudioInterface(int input, int output, jack_nframes_t buffer_size, jack_nframes_t sample_rate) :
AudioParam(input, output, buffer_size, sample_rate)
{
fInputCardBuffer = 0;
fOutputCardBuffer = 0;

for (int i = 0; i < 256; i++) {
fInputCardChannels[i] = 0;
fOutputCardChannels[i] = 0;
fInputSoftChannels[i] = 0;
fOutputSoftChannels[i] = 0;
}
}
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(int input, int output, jack_nframes_t buffer_size, jack_nframes_t sample_rate) :
fCardName("hw:0"),
fFrequency(sample_rate),
fBuffering(buffer_size),
fSoftInputs(input),
fSoftOutputs(output)
{}
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; }
AudioParam& inputs(int n) { fSoftInputs = n; return *this; }
AudioParam& outputs(int n) { fSoftOutputs = n; return *this; }
};

/**
* An ALSA audio interface
* Open the audio interface
*/
class AudioInterface : public AudioParam
int open()
{
public:
snd_pcm_t* fOutputDevice;
snd_pcm_t* fInputDevice;
snd_pcm_hw_params_t* fInputParams;
snd_pcm_hw_params_t* fOutputParams;
snd_pcm_format_t fSampleFormat;
snd_pcm_access_t fSampleAccess;
unsigned int fCardInputs;
unsigned int fCardOutputs;
unsigned int fChanInputs;
unsigned int fChanOutputs;
// 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
float* fInputSoftChannels[256];
float* fOutputSoftChannels[256];

public:
const char* cardName() { return fCardName; }
int frequency() { return fFrequency; }
int buffering() { return fBuffering; }
float** inputSoftChannels() { return fInputSoftChannels; }
float** outputSoftChannels() { return fOutputSoftChannels; }
AudioInterface(const AudioParam& ap = AudioParam()) : AudioParam(ap)
{
fInputDevice = 0;
fOutputDevice = 0;
fInputParams = 0;
fOutputParams = 0;
}

AudioInterface(int input, int output, jack_nframes_t buffer_size, jack_nframes_t sample_rate) :
AudioParam(input, output, buffer_size, sample_rate)
{
fInputCardBuffer = 0;
fOutputCardBuffer = 0;

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()
{
int err;
// allocation d'un stream d'entree et d'un stream de sortie
err = snd_pcm_open(&fInputDevice, fCardName, SND_PCM_STREAM_CAPTURE, 0); check_error(err)
err = snd_pcm_open(&fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0); check_error(err)

// recherche des parametres d'entree
err = snd_pcm_hw_params_malloc(&fInputParams); check_error(err);
setAudioParams(fInputDevice, fInputParams);
snd_pcm_hw_params_get_channels(fInputParams, &fCardInputs);

// recherche des parametres de sortie
err = snd_pcm_hw_params_malloc(&fOutputParams); check_error(err)
setAudioParams(fOutputDevice, fOutputParams);
snd_pcm_hw_params_get_channels(fOutputParams, &fCardOutputs);

jack_info("inputs : %ud, outputs : %ud", fCardInputs, fCardOutputs);

// enregistrement des parametres d'entree-sortie
err = snd_pcm_hw_params(fInputDevice, fInputParams); check_error (err);
err = snd_pcm_hw_params(fOutputDevice, fOutputParams); check_error (err);

// allocation of alsa 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);
}
}
// allocation of floating point buffers needed by the dsp code
fChanInputs = max(fSoftInputs, fCardInputs); assert (fChanInputs < 256);
fChanOutputs = max(fSoftOutputs, fCardOutputs); assert (fChanOutputs < 256);

for (unsigned int i = 0; i < fChanInputs; i++) {
fInputSoftChannels[i] = (float*) aligned_calloc (fBuffering, sizeof(float));
for (int j = 0; j < fBuffering; j++) {
fInputSoftChannels[i][j] = 0.0;
}
int err;
// allocation d'un stream d'entree et d'un stream de sortie
err = snd_pcm_open(&fInputDevice, fCardName, SND_PCM_STREAM_CAPTURE, 0); check_error(err)
err = snd_pcm_open(&fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0); check_error(err)

// recherche des parametres d'entree
err = snd_pcm_hw_params_malloc(&fInputParams); check_error(err);
setAudioParams(fInputDevice, fInputParams);
snd_pcm_hw_params_get_channels(fInputParams, &fCardInputs);

// recherche des parametres de sortie
err = snd_pcm_hw_params_malloc(&fOutputParams); check_error(err)
setAudioParams(fOutputDevice, fOutputParams);
snd_pcm_hw_params_get_channels(fOutputParams, &fCardOutputs);

jack_info("inputs : %ud, outputs : %ud", fCardInputs, fCardOutputs);

// enregistrement des parametres d'entree-sortie
err = snd_pcm_hw_params(fInputDevice, fInputParams); check_error (err);
err = snd_pcm_hw_params(fOutputDevice, fOutputParams); check_error (err);

// allocation of alsa 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 < fChanOutputs; i++) {
fOutputSoftChannels[i] = (float*) aligned_calloc (fBuffering, sizeof(float));
for (int j = 0; j < fBuffering; j++) {
fOutputSoftChannels[i][j] = 0.0;
}
for (unsigned int i = 0; i < fCardOutputs; i++) {
fOutputCardChannels[i] = aligned_calloc(noninterleavedBufferSize(fOutputParams), 1);
}
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 < fChanInputs; i++) {
if (fInputSoftChannels[i])
free(fInputSoftChannels[i]);
}

for (unsigned int i = 0; i < fChanOutputs; i++) {
if (fOutputSoftChannels[i])
free(fOutputSoftChannels[i]);
// allocation of floating point buffers needed by the dsp code
fChanInputs = max(fSoftInputs, fCardInputs); assert (fChanInputs < 256);
fChanOutputs = max(fSoftOutputs, fCardOutputs); assert (fChanOutputs < 256);

for (unsigned int i = 0; i < fChanInputs; i++) {
fInputSoftChannels[i] = (float*) aligned_calloc (fBuffering, sizeof(float));
for (int j = 0; j < fBuffering; j++) {
fInputSoftChannels[i][j] = 0.0;
}
}

for (unsigned int i = 0; i < fCardInputs; i++) {
if (fInputCardChannels[i])
free(fInputCardChannels[i]);
for (unsigned int i = 0; i < fChanOutputs; i++) {
fOutputSoftChannels[i] = (float*) aligned_calloc (fBuffering, sizeof(float));
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 < fChanInputs; i++) {
if (fInputSoftChannels[i])
free(fInputSoftChannels[i]);
}

for (unsigned int i = 0; i < fCardOutputs; i++) {
if (fOutputCardChannels[i])
free(fOutputCardChannels[i]);
}
for (unsigned int i = 0; i < fChanOutputs; i++) {
if (fOutputSoftChannels[i])
free(fOutputSoftChannels[i]);
}

if (fInputCardBuffer)
free(fInputCardBuffer);
if (fOutputCardBuffer)
free(fOutputCardBuffer);
return 0;
for (unsigned int i = 0; i < fCardInputs; i++) {
if (fInputCardChannels[i])
free(fInputCardChannels[i]);
}
int setAudioParams(snd_pcm_t* stream, snd_pcm_hw_params_t* params)
{
int err;

// set params record with initial values
err = snd_pcm_hw_params_any ( stream, params );
check_error_msg(err, "unable to init parameters")
for (unsigned int i = 0; i < fCardOutputs; i++) {
if (fOutputCardChannels[i])
free(fOutputCardChannels[i]);
}

// set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved
err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
if (err) {
err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_INTERLEAVED );
check_error_msg(err, "unable to set access mode neither to non-interleaved or to interleaved");
}
snd_pcm_hw_params_get_access(params, &fSampleAccess);
if (fInputCardBuffer)
free(fInputCardBuffer);
if (fOutputCardBuffer)
free(fOutputCardBuffer);
return 0;
}
int setAudioParams(snd_pcm_t* stream, snd_pcm_hw_params_t* params)
{
int err;

// search for 32-bits or 16-bits format
err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S32);
if (err) {
err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S16);
check_error_msg(err, "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 params record with initial values
err = snd_pcm_hw_params_any ( stream, params );
check_error_msg(err, "unable to init parameters")

// set period and period size (buffering)
err = snd_pcm_hw_params_set_period_size (stream, params, fBuffering, 0);
check_error_msg(err, "period size not available");
err = snd_pcm_hw_params_set_periods (stream, params, 2, 0);
check_error_msg(err, "number of periods not available");
return 0;
// set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved
err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
if (err) {
err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_INTERLEAVED );
check_error_msg(err, "unable to set access mode neither to non-interleaved or to interleaved");
}
snd_pcm_hw_params_get_access(params, &fSampleAccess);

ssize_t interleavedBufferSize(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);
unsigned int channels; snd_pcm_hw_params_get_channels(params, &channels);
ssize_t bsize = snd_pcm_format_size(format, psize * channels);
return bsize;
// search for 32-bits or 16-bits format
err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S32);
if (err) {
err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S16);
check_error_msg(err, "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);

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;
}
// set period and period size (buffering)
err = snd_pcm_hw_params_set_period_size (stream, params, fBuffering, 0);
check_error_msg(err, "period size not available");
err = snd_pcm_hw_params_set_periods (stream, params, 2, 0);
check_error_msg(err, "number of periods not available");
return 0;
}

/**
* Read audio samples from the audio card. Convert samples to floats and take
* care of interleaved buffers
*/
int read()
{
if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
int count = snd_pcm_readi(fInputDevice, fInputCardBuffer, fBuffering);
if (count<0) {
display_error_msg(count, "reading samples");
int err = snd_pcm_prepare(fInputDevice);
check_error_msg(err, "preparing input stream");
}
if (fSampleFormat == SND_PCM_FORMAT_S16) {
ssize_t interleavedBufferSize(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);
unsigned int channels; 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;
}

short* buffer16b = (short*) fInputCardBuffer;
for (int s = 0; s < fBuffering; s++) {
for (unsigned int c = 0; c < fCardInputs; c++) {
fInputSoftChannels[c][s] = float(buffer16b[c + s*fCardInputs])*(1.0/float(SHRT_MAX));
}
/**
* Read audio samples from the audio card. Convert samples to floats and take
* care of interleaved buffers
*/
int read()
{
if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
int count = snd_pcm_readi(fInputDevice, fInputCardBuffer, fBuffering);
if (count<0) {
display_error_msg(count, "reading samples");
int err = snd_pcm_prepare(fInputDevice);
check_error_msg(err, "preparing input stream");
}
if (fSampleFormat == SND_PCM_FORMAT_S16) {

short* buffer16b = (short*) fInputCardBuffer;
for (int s = 0; s < fBuffering; s++) {
for (unsigned int c = 0; c < fCardInputs; c++) {
fInputSoftChannels[c][s] = float(buffer16b[c + s*fCardInputs])*(1.0/float(SHRT_MAX));
}
}

} else { // SND_PCM_FORMAT_S32
} else { // SND_PCM_FORMAT_S32

long* buffer32b = (long*) fInputCardBuffer;
for (int s = 0; s < fBuffering; s++) {
for (unsigned int c = 0; c < fCardInputs; c++) {
fInputSoftChannels[c][s] = float(buffer32b[c + s*fCardInputs])*(1.0/float(LONG_MAX));
}
long* buffer32b = (long*) fInputCardBuffer;
for (int s = 0; s < fBuffering; s++) {
for (unsigned int c = 0; c < fCardInputs; c++) {
fInputSoftChannels[c][s] = float(buffer32b[c + s*fCardInputs])*(1.0/float(LONG_MAX));
}
}
} else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
int count = snd_pcm_readn(fInputDevice, fInputCardChannels, fBuffering);
if (count < 0) {
display_error_msg(count, "reading samples");
int err = snd_pcm_prepare(fInputDevice);
check_error_msg(err, "preparing input stream");
}
if (fSampleFormat == SND_PCM_FORMAT_S16) {
}
} else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
int count = snd_pcm_readn(fInputDevice, fInputCardChannels, fBuffering);
if (count < 0) {
display_error_msg(count, "reading samples");
int err = snd_pcm_prepare(fInputDevice);
check_error_msg(err, "preparing input stream");
}
if (fSampleFormat == SND_PCM_FORMAT_S16) {

for (unsigned int c = 0; c < fCardInputs; c++) {
short* chan16b = (short*) fInputCardChannels[c];
for (int s = 0; s < fBuffering; s++) {
fInputSoftChannels[c][s] = float(chan16b[s])*(1.0/float(SHRT_MAX));
}
for (unsigned int c = 0; c < fCardInputs; c++) {
short* chan16b = (short*) fInputCardChannels[c];
for (int s = 0; s < fBuffering; s++) {
fInputSoftChannels[c][s] = float(chan16b[s])*(1.0/float(SHRT_MAX));
}
}

} else { // SND_PCM_FORMAT_S32
} else { // SND_PCM_FORMAT_S32

for (unsigned int c = 0; c < fCardInputs; c++) {
long* chan32b = (long*) fInputCardChannels[c];
for (int s = 0; s < fBuffering; s++) {
fInputSoftChannels[c][s] = float(chan32b[s])*(1.0/float(LONG_MAX));
}
for (unsigned int c = 0; c < fCardInputs; c++) {
long* chan32b = (long*) fInputCardChannels[c];
for (int s = 0; s < fBuffering; s++) {
fInputSoftChannels[c][s] = float(chan32b[s])*(1.0/float(LONG_MAX));
}
}
} else {
check_error_msg(-10000, "unknow access mode");
}

return 0;
} else {
check_error_msg(-10000, "unknow access mode");
}

/**
* write the output soft channels to the audio card. Convert sample
* format and interleaves buffers when needed
*/
int write()
{
recovery:
if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
if (fSampleFormat == SND_PCM_FORMAT_S16) {

short* buffer16b = (short*) fOutputCardBuffer;
for (int f = 0; f < fBuffering; f++) {
for (unsigned int c = 0; c < fCardOutputs; c++) {
float x = fOutputSoftChannels[c][f];
buffer16b[c + f * fCardOutputs] = short(max(min(x, 1.0), -1.0) * float(SHRT_MAX));
}
}
return 0;
}

} else { // SND_PCM_FORMAT_S32
/**
* write the output soft channels to the audio card. Convert sample
* format and interleaves buffers when needed
*/
int write()
{
recovery:
if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) {
if (fSampleFormat == SND_PCM_FORMAT_S16) {

long* buffer32b = (long*) fOutputCardBuffer;
for (int f = 0; f < fBuffering; f++) {
for (unsigned int c = 0; c < fCardOutputs; c++) {
float x = fOutputSoftChannels[c][f];
buffer32b[c + f * fCardOutputs] = long( max(min(x, 1.0), -1.0) * float(LONG_MAX));
}
short* buffer16b = (short*) fOutputCardBuffer;
for (int f = 0; f < fBuffering; f++) {
for (unsigned int c = 0; c < fCardOutputs; c++) {
float x = fOutputSoftChannels[c][f];
buffer16b[c + f * fCardOutputs] = short(max(min(x, 1.0), -1.0) * float(SHRT_MAX));
}
}

int 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;
}
} else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
if (fSampleFormat == SND_PCM_FORMAT_S16) {
} else { // SND_PCM_FORMAT_S32

long* buffer32b = (long*) fOutputCardBuffer;
for (int f = 0; f < fBuffering; f++) {
for (unsigned int c = 0; c < fCardOutputs; c++) {
short* chan16b = (short*) fOutputCardChannels[c];
for (int f = 0; f < fBuffering; f++) {
float x = fOutputSoftChannels[c][f];
chan16b[f] = short(max(min(x,1.0), -1.0) * float(SHRT_MAX)) ;
}
float x = fOutputSoftChannels[c][f];
buffer32b[c + f * fCardOutputs] = long( max(min(x, 1.0), -1.0) * float(LONG_MAX));
}
}
}

} else { // SND_PCM_FORMAT_S32
int 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;
}
} else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
if (fSampleFormat == SND_PCM_FORMAT_S16) {

for (unsigned int c = 0; c < fCardOutputs; c++) {
long* chan32b = (long*) fOutputCardChannels[c];
for (int f = 0; f < fBuffering; f++) {
float x = fOutputSoftChannels[c][f];
chan32b[f] = long(max(min(x,1.0),-1.0) * float(LONG_MAX)) ;
}
for (unsigned int c = 0; c < fCardOutputs; c++) {
short* chan16b = (short*) fOutputCardChannels[c];
for (int f = 0; f < fBuffering; f++) {
float x = fOutputSoftChannels[c][f];
chan16b[f] = short(max(min(x,1.0), -1.0) * float(SHRT_MAX)) ;
}
}

int 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;
} else { // SND_PCM_FORMAT_S32

for (unsigned int c = 0; c < fCardOutputs; c++) {
long* chan32b = (long*) fOutputCardChannels[c];
for (int f = 0; f < fBuffering; f++) {
float x = fOutputSoftChannels[c][f];
chan32b[f] = long(max(min(x,1.0),-1.0) * float(LONG_MAX)) ;
}
}
} else {
check_error_msg(-10000, "unknow access mode");
}

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));
}
/**
* print more detailled information on the audio device
*/
int longinfo()
{
int err;
snd_ctl_card_info_t* card_info;
snd_ctl_t* ctl_handle;

jack_info("Audio Interface Description :");
jack_info("Sampling Frequency : %d, Sample Format : %s, buffering : %d",
fFrequency, snd_pcm_format_name((_snd_pcm_format)fSampleFormat), fBuffering);
jack_info("Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs);
jack_info("Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs);
jack_info("Channel inputs : %2d, Channel outputs : %2d", fChanInputs, fChanOutputs);
int 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;
}
// affichage des infos de la carte
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);
printCardInfo(card_info);

// affichage des infos liees aux streams d'entree-sortie
if (fSoftInputs > 0) printHWParams(fInputParams);
if (fSoftOutputs > 0) printHWParams(fOutputParams);
return 0;
} else {
check_error_msg(-10000, "unknow access mode");
}

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));
}
/**
* print more detailled information on the audio device
*/
int longinfo()
{
int err;
snd_ctl_card_info_t* card_info;
snd_ctl_t* ctl_handle;

jack_info("Audio Interface Description :");
jack_info("Sampling Frequency : %d, Sample Format : %s, buffering : %d",
fFrequency, snd_pcm_format_name((_snd_pcm_format)fSampleFormat), fBuffering);
jack_info("Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs);
jack_info("Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs);
jack_info("Channel inputs : %2d, Channel outputs : %2d", fChanInputs, fChanOutputs);
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("--------------");
}
// affichage des infos de la carte
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);
printCardInfo(card_info);

// affichage des infos liees aux streams d'entree-sortie
if (fSoftInputs > 0) printHWParams(fInputParams);
if (fSoftOutputs > 0) printHWParams(fOutputParams);
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));
jack_info("\tFormat = %s", snd_pcm_format_name((_snd_pcm_format)snd_pcm_hw_params_get_format(params)));
jack_info("\tAccess = %s", snd_pcm_access_name((_snd_pcm_access)snd_pcm_hw_params_get_access(params)));
jack_info("\tRate = %d", snd_pcm_hw_params_get_rate(params, NULL));
jack_info("\tPeriods = %d", snd_pcm_hw_params_get_periods(params, NULL));
jack_info("\tPeriod size = %d", (int)snd_pcm_hw_params_get_period_size(params, NULL));
jack_info("\tPeriod time = %d", snd_pcm_hw_params_get_period_time(params, NULL));
jack_info("\tBuffer size = %d", (int)snd_pcm_hw_params_get_buffer_size(params));
jack_info("\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time(params, NULL));
#endif
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));
jack_info("\tFormat = %s", snd_pcm_format_name((_snd_pcm_format)snd_pcm_hw_params_get_format(params)));
jack_info("\tAccess = %s", snd_pcm_access_name((_snd_pcm_access)snd_pcm_hw_params_get_access(params)));
jack_info("\tRate = %d", snd_pcm_hw_params_get_rate(params, NULL));
jack_info("\tPeriods = %d", snd_pcm_hw_params_get_periods(params, NULL));
jack_info("\tPeriod size = %d", (int)snd_pcm_hw_params_get_period_size(params, NULL));
jack_info("\tPeriod time = %d", snd_pcm_hw_params_get_period_time(params, NULL));
jack_info("\tBuffer size = %d", (int)snd_pcm_hw_params_get_buffer_size(params));
jack_info("\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time(params, NULL));
#endif
jack_info("--------------");
}
};
/*!
\brief Audio adapter suing ALSA API.
*/

class JackAlsaAdapter : public JackAudioAdapterInterface, public JackRunnableInterface
{
class JackAlsaAdapter : public JackAudioAdapterInterface, public JackRunnableInterface
{

private:
JackThread fThread;
AudioInterface fAudioInterface;
public:
private:
JackThread fThread;
AudioInterface fAudioInterface;
public:
JackAlsaAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params);
~JackAlsaAdapter()
{}
JackAlsaAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params);
~JackAlsaAdapter()
{}
virtual int Open();
virtual int Close();
virtual int SetBufferSize(jack_nframes_t buffer_size);
virtual bool Init();
virtual bool Execute();
};
virtual int Open();
virtual int Close();
virtual int SetBufferSize(jack_nframes_t buffer_size);
virtual bool Init();
virtual bool Execute();
};

}

#ifdef __cplusplus


+ 77
- 73
macosx/JackCoreAudioAdapter.h View File

@@ -30,83 +30,87 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack
{

typedef UInt8 CAAudioHardwareDeviceSectionID;
#define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01)
#define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00)
#define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00)
#define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF)

class JackCoreAudioAdapter : public JackAudioAdapterInterface
{
typedef UInt8 CAAudioHardwareDeviceSectionID;
#define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01)
#define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00)
#define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00)
#define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF)

/*!
\brief Audio adapter using CoreAudio API.
*/

class JackCoreAudioAdapter : public JackAudioAdapterInterface
{

private:
private:
AudioUnit fAUHAL;
AudioBufferList* fInputData;
AudioUnit fAUHAL;
AudioBufferList* fInputData;
AudioDeviceID fDeviceID;
bool fState;

AudioUnitRenderActionFlags* fActionFags;
AudioTimeStamp* fCurrentTime;
static OSStatus Render(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData);
static OSStatus SRNotificationCallback(AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData);

OSStatus GetDefaultDevice(AudioDeviceID* id);
OSStatus GetTotalChannels(AudioDeviceID device, int* channelCount, bool isInput);

// Setup
int SetupDevices(const char* capture_driver_uid,
const char* playback_driver_uid,
char* capture_driver_name,
char* playback_driver_name);

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,
bool strict);

int SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size, jack_nframes_t samplerate);
int SetupBuffers(int inchannels, int outchannels);
void DisposeBuffers();
void CloseAUHAL();
AudioDeviceID fDeviceID;
bool fState;

AudioUnitRenderActionFlags* fActionFags;
AudioTimeStamp* fCurrentTime;
static OSStatus Render(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData);
static OSStatus SRNotificationCallback(AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData);

OSStatus GetDefaultDevice(AudioDeviceID* id);
OSStatus GetTotalChannels(AudioDeviceID device, int* channelCount, bool isInput);

// Setup
int SetupDevices(const char* capture_driver_uid,
const char* playback_driver_uid,
char* capture_driver_name,
char* playback_driver_name);

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,
bool strict);

int SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size, jack_nframes_t samplerate);
int SetupBuffers(int inchannels, int outchannels);
void DisposeBuffers();
void CloseAUHAL();

public:
public:
JackCoreAudioAdapter( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params);
~JackCoreAudioAdapter()
{}
virtual int Open();
virtual int Close();
JackCoreAudioAdapter( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params);
~JackCoreAudioAdapter()
{}
virtual int Open();
virtual int Close();
virtual int SetBufferSize(jack_nframes_t buffer_size);
};
virtual int SetBufferSize(jack_nframes_t buffer_size);
};
}

#ifdef __cplusplus


+ 25
- 20
windows/JackPortAudioAdapter.h View File

@@ -27,34 +27,39 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack
{

class JackPortAudioAdapter : public JackAudioAdapterInterface
{
/*!
\brief Audio adapter using PortAudio API.
*/

class JackPortAudioAdapter : public JackAudioAdapterInterface
{

private:

private:
PortAudioDevices fPaDevices;
PaStream* fStream;
PaDeviceIndex fInputDevice;
PaDeviceIndex fOutputDevice;

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);

static int Render(const void* inputBuffer, void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData);
public:

public:
JackPortAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params);
~JackPortAudioAdapter()
{}

JackPortAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params);
~JackPortAudioAdapter()
{}
int Open();
int Close();

int Open();
int Close();
int SetBufferSize(jack_nframes_t buffer_size);

int SetBufferSize(jack_nframes_t buffer_size);
};

};
}

#ifdef __cplusplus


+ 0
- 5
windows/getopt.h View File

@@ -139,11 +139,6 @@ extern "C"

# ifndef __need_getopt

// steph
/*
extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
const struct option *__longopts, int *__longind);
*/
extern int getopt_long (int argc, char ** argv, const char * shortopts,
const struct option * longopts, int * longind);



Loading…
Cancel
Save