Browse Source

Remove checking thread in CoreAudio driver, better device state change recovery strategy: the driver is stopped and restarted. jack_thread_wait implementation. Add jack_thread_wait client example.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1801 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.70
sletz 17 years ago
parent
commit
82bdd90277
12 changed files with 771 additions and 243 deletions
  1. +6
    -0
      ChangeLog
  2. +16
    -1
      common/JackAPI.cpp
  3. +104
    -0
      common/JackClient.cpp
  4. +12
    -1
      common/JackClient.h
  5. +6
    -0
      common/JackPosixThread.cpp
  6. +1
    -0
      common/JackPosixThread.h
  7. +1
    -0
      common/JackThread.h
  8. +228
    -228
      macosx/JackCoreAudioDriver.cpp
  9. +48
    -10
      macosx/JackCoreAudioDriver.h
  10. +338
    -0
      macosx/Jackdmp.xcodeproj/project.pbxproj
  11. +7
    -0
      windows/JackWinThread.cpp
  12. +4
    -3
      windows/JackWinThread.h

+ 6
- 0
ChangeLog View File

@@ -17,6 +17,12 @@ Tim Blechmann
Jackdmp changes log
---------------------------

2008-01-31 Stephane Letz <letz@grame.fr>

* Remove checking thread in CoreAudio driver, better device state change recovery strategy: the driver is stopped and restarted.
* jack_thread_wait implementation.
* Add jack_thread_wait client example.

2008-01-30 Stephane Letz <letz@grame.fr>
* Latest jack_lsp code from jack SVN.


+ 16
- 1
common/JackAPI.cpp View File

@@ -64,7 +64,8 @@ extern "C"
EXPORT int jack_set_process_callback (jack_client_t *client,
JackProcessCallback process_callback,
void *arg);
EXPORT int jack_set_thread_init_callback (jack_client_t *client,
EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status);
EXPORT int jack_set_thread_init_callback (jack_client_t *client,
JackThreadInitCallback thread_init_callback,
void *arg);
EXPORT int jack_set_freewheel_callback (jack_client_t *client,
@@ -630,6 +631,20 @@ EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallb
}
}

EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status)
{
#ifdef __CLIENTDEBUG__
JackLibGlobals::CheckContext();
#endif
JackClient* client = (JackClient*)ext_client;
if (client == NULL) {
jack_error("jack_thread_wait called with a NULL client");
return -1;
} else {
return client->Wait(status);
}
}

EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
{
#ifdef __CLIENTDEBUG__


+ 104
- 0
common/JackClient.cpp View File

@@ -298,11 +298,13 @@ int JackClient::Deactivate()
// RT thread management
//----------------------

/*
bool JackClient::CallProcessCallback()
{
return (fProcess == NULL) ? true : (fProcess(GetEngineControl()->fBufferSize, fProcessArg) == 0);
}

*/
/*!
\brief Called once when the thread starts.
*/
@@ -342,6 +344,7 @@ int JackClient::StartThread()
/*!
\brief RT thread.
*/
/*
bool JackClient::Execute()
{
// Suspend itself: wait on the input synchro
@@ -392,6 +395,107 @@ error:
ShutDown();
return false;
}
*/
////

bool JackClient::Execute()
{
if (WaitFirstSync())
ExecuteThread();
return false; // Never reached
}

inline bool JackClient::WaitFirstSync()
{
while (true) {
// Start first cycle
WaitSync();
if (IsActive()) {
CallSyncCallback();
// Finish first cycle
if (Wait(CallProcessCallback()) != GetEngineControl()->fBufferSize)
return false;
return true;
} else {
JackLog("Process called for an inactive client\n");
}
SignalSync();
}
return false; // Never reached
}

inline void JackClient::ExecuteThread()
{
while (true) {
if (Wait(CallProcessCallback()) != GetEngineControl()->fBufferSize)
return;
}
}

inline int JackClient::End()
{
JackLog("JackClient::Execute end name = %s\n", GetClientControl()->fName);
int result;
// Hum... not sure about this, the following "close" code is called in the RT thread...
fThread->DropRealTime();
GetClientControl()->fActive = false;
fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
fThread->Terminate();
return 0; // Never reached
}

inline int JackClient::Error()
{
jack_error("JackClient::Execute error name = %s", GetClientControl()->fName);
// Hum... not sure about this, the following "close" code is called in the RT thread...
fThread->DropRealTime();
ShutDown();
fThread->Terminate();
return 0; // Never reached
}

jack_nframes_t JackClient::Wait(int status)
{
if (status == 0)
CallTimebaseCallback();
SignalSync();
if (status != 0)
goto end;
if (!WaitSync())
goto error;
CallSyncCallback();
return GetEngineControl()->fBufferSize;
end:
return End();
error:
return Error();
}

inline int JackClient::CallProcessCallback()
{
return (fProcess != NULL) ? fProcess(GetEngineControl()->fBufferSize, fProcessArg) : 0;
}

inline bool JackClient::WaitSync()
{
// Suspend itself: wait on the input synchro
if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable, 0x7FFFFFFF) < 0) {
jack_error("SuspendRefNum error");
return false;
} else {
return true;
}
}

inline void JackClient::SignalSync()
{
// Resume: signal output clients connected to the running client
if (GetGraphManager()->ResumeRefNum(GetClientControl(), fSynchroTable) < 0) {
jack_error("ResumeRefNum error");
}
}

//-----------------
// Port management


+ 12
- 1
common/JackClient.h View File

@@ -90,12 +90,20 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
void SetupDriverSync(bool freewheel);
bool IsActive();

bool CallProcessCallback();
void CallSyncCallback();
void CallTimebaseCallback();
int RequestNewPos(jack_position_t* pos);

virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value);
// Fons Adriaensen thread model
inline bool WaitFirstSync();
inline void ExecuteThread();
inline bool WaitSync();
inline void SignalSync();
inline int CallProcessCallback();
inline int End();
inline int Error();

public:

@@ -161,6 +169,9 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
virtual int InternalClientHandle(const char* client_name, jack_status_t* status);
virtual int InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va);
virtual void InternalClientUnload(int ref, jack_status_t* status);
// Fons Adriaensen thread model
virtual jack_nframes_t Wait(int status);

// JackRunnableInterface interface
bool Init();


+ 6
- 0
common/JackPosixThread.cpp View File

@@ -226,5 +226,11 @@ pthread_t JackPosixThread::GetThreadID()
return fThread;
}

void JackPosixThread::Terminate()
{
JackLog("JackPosixThread::Terminate\n");
pthread_exit(0);
}

} // end of namespace


+ 1
- 0
common/JackPosixThread.h View File

@@ -62,6 +62,7 @@ class JackPosixThread : public JackThread
virtual int StartSync();
virtual int Kill();
virtual int Stop();
virtual void Terminate();

virtual int AcquireRealTime();
virtual int AcquireRealTime(int priority);


+ 1
- 0
common/JackThread.h View File

@@ -81,6 +81,7 @@ class JackThread
virtual int StartSync() = 0;
virtual int Kill() = 0;
virtual int Stop() = 0;
virtual void Terminate() = 0;

virtual int AcquireRealTime() = 0;
virtual int AcquireRealTime(int priority) = 0;


+ 228
- 228
macosx/JackCoreAudioDriver.cpp View File

@@ -257,121 +257,65 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
driver->NotifyXRun(GetMicroSeconds());
break;
case kAudioDevicePropertyDeviceIsRunning: {
UInt32 outSize = sizeof(UInt32);
driver->fStopTime = CFAbsoluteTimeGetCurrent();
OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunning, &outSize, &driver->fRunning);
JackLog("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceIsRunning res = %ld\n", driver->fRunning);
if (err != noErr) {
jack_error("Cannot getkAudioDevicePropertyDeviceIsRunning");
printError(err);
}
break;
}
case kAudioDevicePropertyStreamConfiguration:
JackLog("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyStreamConfiguration \n");
//JackLog("GetTotalNumberChannels input = %ld\n", GetTotalNumberChannels(driver->fDeviceID, true));
//JackLog("GetTotalNumberChannels output = %ld\n", GetTotalNumberChannels(driver->fDeviceID, false));
break;
case kAudioDevicePropertyNominalSampleRate: {
OSStatus err;
UInt32 outSize = sizeof(Float64);
UInt32 outSize = sizeof(Float64);
Float64 sampleRate;
int in_nChannels = 0;
int out_nChannels = 0;
char capture_driver_name[256];
char playback_driver_name[256];
return noErr; // for now
// Stop and restart
driver->Stop();
driver->RemoveListeners();
driver->CloseAUHAL();
err = AudioOutputUnitStop(driver->fAUHAL);
if (err != noErr)
jack_error("Error calling AudioOutputUnitStop");
AudioStreamBasicDescription srcFormat, dstFormat;
err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
if (err != noErr) {
jack_error("Cannot get current sample rate");
printError(err);
return kAudioHardwareUnsupportedOperationError;
}
JackLog("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyNominalSampleRate %ld\n", long(sampleRate));
if (sampleRate != driver->fEngineControl->fSampleRate) {
// To get SR change notification
/*
driver->fState = false;
err = AudioDeviceAddPropertyListener(driver->fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, driver);
if (err != noErr) {
jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate");
printError(err);
return kAudioHardwareUnsupportedOperationError;
}
*/
//sampleRate = driver->fEngineControl->fSampleRate;
err = AudioDeviceSetProperty(driver->fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate);
if (err != noErr) {
jack_error("Cannot set sample rate = %ld", sampleRate);
printError(err);
return kAudioHardwareUnsupportedOperationError;
}
JackLog("JackCoreAudioDriver::DeviceNotificationCallback sampleRate %ld\n", driver->fEngineControl->fSampleRate);
/*
// Waiting for SR change notification
int count = 0;
while (!driver->fState && count++ < 100) {
usleep(100000);
JackLog("Wait count = %ld\n", count);
}
// Remove SR change notification
AudioDeviceRemovePropertyListener(driver->fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback);
*/
}
/*
// Update SR for input
//Float64 sampleRate = driver->fEngineControl->fSampleRate;
outSize = sizeof(AudioStreamBasicDescription);
err = AudioUnitGetProperty(driver->fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, &outSize);
if (err != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input");
printError(err);
}
srcFormat.mSampleRate = sampleRate;
//srcFormat.mSampleRate = driver->fEngineControl->fSampleRate;
err = AudioUnitSetProperty(driver->fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, outSize);
if (err != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input");
printError(err);
}
if (driver->SetupDevices(driver->fCaptureUID, driver->fPlaybackUID, capture_driver_name, playback_driver_name) < 0)
return -1;
// Update SR for output
err = AudioUnitGetProperty(driver->fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat, &outSize);
if (err != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output");
printError(err);
}
dstFormat.mSampleRate = sampleRate;
//dstFormat.mSampleRate = driver->fEngineControl->fSampleRate;
err = AudioUnitSetProperty(driver->fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat, outSize);
if (err != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output");
printError(err);
}
*/
if (driver->SetupChannels(driver->fCapturing, driver->fPlaying, driver->fInChannels, driver->fOutChannels, in_nChannels, out_nChannels, false) < 0)
return -1;
if (driver->SetupBufferSizeAndSampleRate(driver->fEngineControl->fBufferSize, sampleRate) < 0)
return -1;

if (driver->OpenAUHAL(driver->fCapturing,
driver->fPlaying,
driver->fInChannels,
driver->fOutChannels,
in_nChannels,
out_nChannels,
driver->fEngineControl->fBufferSize,
sampleRate,
false) < 0)
goto error;

if (driver->AddListeners() < 0)
goto error;
driver->Start();
err = AudioOutputUnitStart(driver->fAUHAL);
if (err != noErr)
jack_error("Error calling AudioOutputUnitStart");
// Send notification to be used in JackPilot or JackRouter plugin
jack_error("Device restart...");
CFStringRef ref = CFStringCreateWithCString(NULL, driver->fEngineControl->fServerName, kCFStringEncodingMacRoman);
CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(),
CFSTR("com.grame.jackserver.restart"),
ref,
NULL,
kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions);
CFRelease(ref);
return noErr;
error:
driver->CloseAUHAL();
break;
}
}
@@ -453,7 +397,7 @@ OSStatus JackCoreAudioDriver::GetDeviceNameFromID(AudioDeviceID id, char* name)
return AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, name);
}

OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, long* channelCount, bool isInput)
OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int* channelCount, bool isInput)
{
OSStatus err = noErr;
UInt32 outSize;
@@ -478,12 +422,11 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, long* chann
}

JackCoreAudioDriver::JackCoreAudioDriver(const char* name, JackEngine* engine, JackSynchro** table)
: JackAudioDriver(name, engine, table), fJackInputData(NULL), fDriverOutputData(NULL), fState(false), fStopTime(0), fRunning(true)
: JackAudioDriver(name, engine, table), fJackInputData(NULL), fDriverOutputData(NULL), fState(false)
{
#ifdef DEBUG
//fLogFile = new CALatencyLog("jackmp_latency", ".txt");
#endif
fThread = JackGlobals::MakeThread(this);
}

JackCoreAudioDriver::~JackCoreAudioDriver()
@@ -491,60 +434,14 @@ JackCoreAudioDriver::~JackCoreAudioDriver()
#ifdef DEBUG
//delete fLogFile;
#endif
fThread->Kill();
delete fThread;
}

bool JackCoreAudioDriver::Execute()
{
while (true) {
JackLog("Check device running...\n");
if (!fRunning && CFAbsoluteTimeGetCurrent() > fStopTime + 3.0) {
jack_error("Critical error : device not running anymore...");
// Send notification to be used in JackPilot or JackRouter plugin
CFStringRef ref = CFStringCreateWithCString(NULL, fEngineControl->fServerName, kCFStringEncodingMacRoman);
CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(),
CFSTR("com.grame.jackserver.stop"),
ref,
NULL,
kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions);
CFRelease(ref);
}
usleep(2000000);
}
return false;
}

int JackCoreAudioDriver::Open(jack_nframes_t nframes,
jack_nframes_t samplerate,
bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_uid,
const char* playback_driver_uid,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name)
{
OSStatus err = noErr;
ComponentResult err1;
UInt32 outSize;
UInt32 enableIO;
AudioStreamBasicDescription srcFormat, dstFormat;
Float64 sampleRate;

long in_nChannels = 0;
long out_nChannels = 0;
char capture_driver_name[256];
char playback_driver_name[256];
capture_driver_name[0] = 0;
capture_driver_name[0] = 0;
playback_driver_name[0] = 0;

JackLog("JackCoreAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s\n",
nframes, inchannels, outchannels, capture_driver_uid, playback_driver_uid);

// Duplex
// Duplex
if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) {
JackLog("JackCoreAudioDriver::Open duplex \n");
if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) {
@@ -598,13 +495,15 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
return -1;
}
}
return 0;
}

// Generic JackAudioDriver Open
if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) {
return -1;
}
if (capturing) {
int JackCoreAudioDriver::SetupChannels(int capturing, int playing, int& inchannels, int& outchannels, int& in_nChannels, int& out_nChannels, bool strict)
{
OSStatus err = noErr;
if (capturing) {
err = GetTotalChannels(fDeviceID, &in_nChannels, true);
if (err != noErr) {
jack_error("Cannot get input channel number");
@@ -624,12 +523,14 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,

if (inchannels > in_nChannels) {
jack_error("This device hasn't required input channels inchannels = %ld in_nChannels = %ld", inchannels, in_nChannels);
return -1;
}
if (strict)
return -1;
}

if (outchannels > out_nChannels) {
jack_error("This device hasn't required output channels outchannels = %ld out_nChannels = %ld", outchannels, out_nChannels);
return -1;
if (strict)
return -1;
}

if (inchannels == 0) {
@@ -641,10 +542,19 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
JackLog("Setup max out channels = %ld\n", out_nChannels);
outchannels = out_nChannels;
}
return 0;
}

// Setting buffer size
int JackCoreAudioDriver::SetupBufferSizeAndSampleRate(jack_nframes_t nframes, jack_nframes_t samplerate)
{
OSStatus err = noErr;
UInt32 outSize;
Float64 sampleRate;
// Setting buffer size
outSize = sizeof(UInt32);
err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &fEngineControl->fBufferSize);
err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &nframes);
if (err != noErr) {
jack_error("Cannot set buffer size %ld", nframes);
printError(err);
@@ -688,8 +598,25 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
// Remove SR change notification
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback);
}
return 0;
}

// AUHAL
int JackCoreAudioDriver::OpenAUHAL(int capturing,
int playing,
int inchannels,
int outchannels,
int in_nChannels,
int out_nChannels,
jack_nframes_t nframes,
jack_nframes_t samplerate,
bool strict)
{
ComponentResult err1;
UInt32 enableIO;
AudioStreamBasicDescription srcFormat, dstFormat;
// AUHAL
ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
Component HALOutput = FindNextComponent(NULL, &cd);

@@ -697,14 +624,14 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
if (err1 != noErr) {
jack_error("Error calling OpenAComponent");
printError(err1);
goto error;
return -1;
}

err1 = AudioUnitInitialize(fAUHAL);
if (err1 != noErr) {
jack_error("Cannot initialize AUHAL unit");
printError(err1);
goto error;
return -1;
}

// Start I/O
@@ -715,7 +642,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input");
printError(err1);
goto error;
if (strict)
return -1;
}
}

@@ -725,7 +653,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output");
printError(err1);
goto error;
if (strict)
return -1;
}
}

@@ -734,7 +663,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice");
printError(err1);
goto error;
if (strict)
return -1;
}

// Set buffer size
@@ -743,7 +673,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice");
printError(err1);
goto error;
if (strict)
return -1;
}
}

@@ -752,7 +683,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice");
printError(err1);
goto error;
if (strict)
return -1;
}
}

@@ -829,7 +761,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1");
printError(err1);
goto error;
return -1;
}
} else {
AURenderCallbackStruct output;
@@ -839,98 +771,174 @@ int JackCoreAudioDriver::Open(jack_nframes_t nframes,
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0");
printError(err1);
goto error;
return -1;
}
}

// Prepare buffers
if (capturing && inchannels > 0) {
fJackInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer));
if (fJackInputData == 0) {
jack_error("Cannot allocate memory for input buffers");
goto error;
}
fJackInputData->mNumberBuffers = inchannels;
for (int i = 0; i < fCaptureChannels; i++) {
fJackInputData->mBuffers[i].mNumberChannels = 1;
fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(float);
}
}
return 0;
}

int JackCoreAudioDriver::SetupBuffers(int inchannels, int outchannels)
{
// Prepare buffers
fJackInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer));
if (fJackInputData == 0) {
jack_error("Cannot allocate memory for input buffers");
return -1;
}
fJackInputData->mNumberBuffers = inchannels;
for (int i = 0; i < fCaptureChannels; i++) {
fJackInputData->mBuffers[i].mNumberChannels = 1;
fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(float);
}
return 0;
}

void JackCoreAudioDriver::DisposeBuffers()
{
if (fJackInputData) {
free(fJackInputData);
fJackInputData = 0;
}
}

void JackCoreAudioDriver::CloseAUHAL()
{
AudioUnitUninitialize(fAUHAL);
CloseComponent(fAUHAL);
}

// Add listeners
int JackCoreAudioDriver::AddListeners()
{
OSStatus err = noErr;
// Add listeners
err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this);
if (err != noErr) {
jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload");
printError(err1);
goto error;
printError(err);
return -1;
}

err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback, this);
if (err != noErr) {
jack_error("Error calling AudioDeviceAddPropertyListener with kAudioHardwarePropertyDevices");
printError(err1);
goto error;
printError(err);
return -1;
}
err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback, this);
if (err != noErr) {
jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate");
printError(err1);
goto error;
printError(err);
return -1;
}
err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback, this);
if (err != noErr) {
jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyDeviceIsRunning");
printError(err1);
goto error;
printError(err);
return -1;
}
err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback, this);
if (err != noErr) {
jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyStreamConfiguration");
printError(err1);
goto error;
printError(err);
return -1;
}

err = AudioDeviceAddPropertyListener(fDeviceID, 0, false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback, this);
if (err != noErr) {
jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyStreamConfiguration");
printError(err1);
goto error;
printError(err);
return -1;
}

fDriverOutputData = 0;
return 0;
}

void JackCoreAudioDriver::RemoveListeners()
{
AudioDeviceRemoveIOProc(fDeviceID, MeasureCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback);
}

int JackCoreAudioDriver::Open(jack_nframes_t nframes,
jack_nframes_t samplerate,
bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_uid,
const char* playback_driver_uid,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
{
int in_nChannels = 0;
int out_nChannels = 0;
char capture_driver_name[256];
char playback_driver_name[256];
// Keep initial state
fCapturing = capturing;
fPlaying = playing;
fInChannels = inchannels;
fOutChannels = outchannels;
fMonitor = monitor;
strcpy(fCaptureUID, capture_driver_uid);
strcpy(fPlaybackUID, playback_driver_uid);
fCaptureLatency = capture_latency;
fPlaybackLatency = playback_latency;
if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name) < 0)
return -1;
// Generic JackAudioDriver Open
if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0)
return -1;
if (SetupChannels(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, true) < 0)
return -1;
if (SetupBufferSizeAndSampleRate(nframes, samplerate) < 0)
return -1;

if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, nframes, samplerate, true) < 0)
goto error;
if (capturing && inchannels > 0)
if (SetupBuffers(inchannels, outchannels) < 0)
goto error;

if (AddListeners() < 0)
goto error;
// Core driver may have changed the in/out values
fCaptureChannels = inchannels;
fPlaybackChannels = outchannels;
return noErr;

error:
AudioUnitUninitialize(fAUHAL);
CloseComponent(fAUHAL);
Close();
return -1;
}

int JackCoreAudioDriver::Close()
{
JackLog("JackCoreAudioDriver::Close\n");
Stop();
JackAudioDriver::Close();
// Possibly (if MeasureCallback has not been called)
AudioDeviceStop(fDeviceID, MeasureCallback);
AudioDeviceRemoveIOProc(fDeviceID, MeasureCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback);
AudioDeviceRemovePropertyListener(fDeviceID, 0, false, kAudioDevicePropertyStreamConfiguration, DeviceNotificationCallback);
free(fJackInputData);
AudioUnitUninitialize(fAUHAL);
CloseComponent(fAUHAL);
return 0;
RemoveListeners();
DisposeBuffers();
CloseAUHAL();
return 0;
}

int JackCoreAudioDriver::Attach()
@@ -978,7 +986,6 @@ int JackCoreAudioDriver::Attach()
port = fGraphManager->GetPort(port_index);
port->Rename("system:capture_%d", i + 1);
port->SetLatency(fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency);
JackLog("Latency = %ld \n", port->GetLatency());
fCapturePortList[i] = port_index;
}

@@ -1016,7 +1023,6 @@ int JackCoreAudioDriver::Attach()
port = fGraphManager->GetPort(port_index);
port->Rename("system:playback_%d", i + 1);
port->SetLatency(fEngineControl->fBufferSize + value1 + value2 + fPlaybackLatency);
JackLog("Latency = %ld \n", port->GetLatency());
fPlaybackPortList[i] = port_index;

// Monitor ports
@@ -1061,20 +1067,14 @@ int JackCoreAudioDriver::Start()
return -1;
}
// Start checking thread...
fRunning = true;
fThread->Start();
return 0;
}

int JackCoreAudioDriver::Stop()
{
JackLog("JackCoreAudioDriver::Stop\n");
AudioDeviceStop(fDeviceID, MeasureCallback);
AudioDeviceRemoveIOProc(fDeviceID, MeasureCallback);
JackLog("JackCoreAudioDriver::Stop\n");
// Kill checking thread...
fThread->Kill();
fRunning = false;
return (AudioOutputUnitStop(fAUHAL) == noErr) ? 0 : -1;
}



+ 48
- 10
macosx/JackCoreAudioDriver.h View File

@@ -25,7 +25,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <AudioUnit/AudioUnit.h>
#include "JackAudioDriver.h"
#include "JackTime.h"
#include "JackThread.h"

#include "/Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.h"

@@ -47,7 +46,7 @@ typedef UInt8 CAAudioHardwareDeviceSectionID;
\todo hardware monitoring
*/

class JackCoreAudioDriver : public JackAudioDriver, public JackRunnableInterface
class JackCoreAudioDriver : public JackAudioDriver
{

private:
@@ -67,9 +66,18 @@ class JackCoreAudioDriver : public JackAudioDriver, public JackRunnableInterfac
AudioTimeStamp* fCurrentTime;
bool fState;
CFAbsoluteTime fStopTime;
UInt32 fRunning;
JackThread* fThread;
/// Intitial state
int fCapturing;
int fPlaying;
int fInChannels;
int fOutChannels;
char fCaptureUID[256];
char fPlaybackUID[256];
bool fMonitor;
static OSStatus Render(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
@@ -104,7 +112,40 @@ class JackCoreAudioDriver : public JackAudioDriver, public JackRunnableInterfac
OSStatus GetDefaultInputDevice(AudioDeviceID* id);
OSStatus GetDefaultOutputDevice(AudioDeviceID* id);
OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name);
OSStatus GetTotalChannels(AudioDeviceID device, long* channelCount, bool isInput);
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(int capturing,
int playing,
int& inchannels,
int& outchannels,
int& in_nChannels,
int& out_nChannels,
bool strict);
int SetupBuffers(int inchannels, int outchannels);
void DisposeBuffers();

int SetupBufferSizeAndSampleRate(jack_nframes_t nframes, jack_nframes_t samplerate);
int OpenAUHAL(int capturing,
int playing,
int inchannels,
int outchannels,
int in_nChannels,
int out_nChannels,
jack_nframes_t nframes,
jack_nframes_t samplerate,
bool strict);
void CloseAUHAL();
int AddListeners();
void RemoveListeners();

public:

@@ -122,8 +163,7 @@ class JackCoreAudioDriver : public JackAudioDriver, public JackRunnableInterfac
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);

int Close();
int Close();

int Attach();

@@ -134,8 +174,6 @@ class JackCoreAudioDriver : public JackAudioDriver, public JackRunnableInterfac
int Write();

int SetBufferSize(jack_nframes_t buffer_size);
bool Execute();
};

} // end of namespace


+ 338
- 0
macosx/Jackdmp.xcodeproj/project.pbxproj View File

@@ -29,6 +29,7 @@
4B35C6920D4733B9000DE7AE /* PBXTargetDependency */,
4B35C6940D4733B9000DE7AE /* PBXTargetDependency */,
4B35C6960D4733B9000DE7AE /* PBXTargetDependency */,
4B0A29300D5210C4002EFF74 /* PBXTargetDependency */,
4B35C6980D4733B9000DE7AE /* PBXTargetDependency */,
4B35C69A0D4733B9000DE7AE /* PBXTargetDependency */,
4B35C69C0D4733B9000DE7AE /* PBXTargetDependency */,
@@ -68,6 +69,7 @@
4BE99D630AD7A19100C59091 /* PBXTargetDependency */,
4BA693E90CBE5BBA00EAD520 /* PBXTargetDependency */,
4BA693EB0CBE5BBA00EAD520 /* PBXTargetDependency */,
4B0A28F40D520D11002EFF74 /* PBXTargetDependency */,
4BFA99AC0AAAF41D009E916C /* PBXTargetDependency */,
4BFA99500AAAED90009E916C /* PBXTargetDependency */,
4BFA99520AAAED90009E916C /* PBXTargetDependency */,
@@ -83,6 +85,8 @@
/* End PBXAggregateTarget section */

/* Begin PBXBuildFile section */
4B0A28ED0D520852002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; };
4B0A29260D52108E002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; };
4B35C41E0D4731D1000DE7AE /* Jackdmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */; };
4B35C4290D4731D1000DE7AE /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; };
4B35C42A0D4731D1000DE7AE /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; };
@@ -596,6 +600,20 @@
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
4B0A28F30D520D11002EFF74 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4B0A28DC0D52073D002EFF74 /* jack_thread_wait */;
remoteInfo = jack_thread_wait;
};
4B0A292F0D5210C4002EFF74 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4B0A29230D52108E002EFF74 /* jack_thread_wait 64 bits */;
remoteInfo = "jack_thread_wait 64 bits";
};
4B1C1ABF0CC61597005F551E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
@@ -986,6 +1004,9 @@
/* Begin PBXFileReference section */
4B003A6008E2A87A0060EFDC /* JackError.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackError.c; path = ../common/JackError.c; sourceTree = SOURCE_ROOT; };
4B003AB008E2B2BA0060EFDC /* ringbuffer.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ringbuffer.c; path = ../common/ringbuffer.c; sourceTree = SOURCE_ROOT; };
4B0A28E60D52073D002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; };
4B0A28EC0D520852002EFF74 /* tw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tw.c; path = "../example-clients/tw.c"; sourceTree = SOURCE_ROOT; };
4B0A292D0D52108E002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; };
4B123D3308B3954300540632 /* JackGlobalsClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobalsClient.cpp; path = ../common/JackGlobalsClient.cpp; sourceTree = SOURCE_ROOT; };
4B123D3608B3954A00540632 /* JackGlobalsServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobalsServer.cpp; path = ../common/JackGlobalsServer.cpp; sourceTree = SOURCE_ROOT; };
4B2C28F908DAD01E00249230 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; };
@@ -1201,6 +1222,20 @@
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
4B0A28E00D52073D002EFF74 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
4B0A29270D52108E002EFF74 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
4B35C41F0D4731D1000DE7AE /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -1680,6 +1715,8 @@
4B35C6290D4731D2000DE7AE /* jack_portaudio.so */,
4B35C6340D4731D2000DE7AE /* jack_dummy.so */,
4B35C63E0D4731D3000DE7AE /* inprocess.so */,
4B0A28E60D52073D002EFF74 /* jack_thread_wait */,
4B0A292D0D52108E002EFF74 /* jack_thread_wait */,
);
name = Products;
sourceTree = "<group>";
@@ -1687,6 +1724,7 @@
4B03383E0797E19900686131 /* Simple clients */ = {
isa = PBXGroup;
children = (
4B0A28EC0D520852002EFF74 /* tw.c */,
4B5A1BDC0CD1CD420005BF74 /* midisine.c */,
4B5A1BBD0CD1CC110005BF74 /* midiseq.c */,
4BA692D60CBE4CC600EAD520 /* ipunload.c */,
@@ -2031,6 +2069,20 @@
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
4B0A28DD0D52073D002EFF74 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
4B0A29240D52108E002EFF74 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
4B35C41C0D4731D1000DE7AE /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
@@ -2646,6 +2698,44 @@
/* End PBXHeadersBuildPhase section */

/* Begin PBXNativeTarget section */
4B0A28DC0D52073D002EFF74 /* jack_thread_wait */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4B0A28E20D52073D002EFF74 /* Build configuration list for PBXNativeTarget "jack_thread_wait" */;
buildPhases = (
4B0A28DD0D52073D002EFF74 /* Headers */,
4B0A28DE0D52073D002EFF74 /* Sources */,
4B0A28E00D52073D002EFF74 /* Frameworks */,
4B0A28E10D52073D002EFF74 /* Rez */,
);
buildRules = (
);
dependencies = (
);
name = jack_thread_wait;
productInstallPath = /usr/local/bin;
productName = testSem;
productReference = 4B0A28E60D52073D002EFF74 /* jack_thread_wait */;
productType = "com.apple.product-type.tool";
};
4B0A29230D52108E002EFF74 /* jack_thread_wait 64 bits */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4B0A29290D52108E002EFF74 /* Build configuration list for PBXNativeTarget "jack_thread_wait 64 bits" */;
buildPhases = (
4B0A29240D52108E002EFF74 /* Headers */,
4B0A29250D52108E002EFF74 /* Sources */,
4B0A29270D52108E002EFF74 /* Frameworks */,
4B0A29280D52108E002EFF74 /* Rez */,
);
buildRules = (
);
dependencies = (
);
name = "jack_thread_wait 64 bits";
productInstallPath = /usr/local/bin;
productName = testSem;
productReference = 4B0A292D0D52108E002EFF74 /* jack_thread_wait */;
productType = "com.apple.product-type.tool";
};
4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4B35C4210D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jackdmp framework 64bits" */;
@@ -3690,6 +3780,7 @@
4BE99D260AD7A04800C59091 /* jack_cpu Universal */,
4BA692A60CBE4BC700EAD520 /* jack_load Universal */,
4BA692CA0CBE4C9000EAD520 /* jack_unload Universal */,
4B0A28DC0D52073D002EFF74 /* jack_thread_wait */,
4B699D4F097D421600A18468 /* synchroServer Universal */,
4B699D67097D421600A18468 /* synchroClient Universal */,
4B699D7F097D421700A18468 /* synchroServerClient Universal */,
@@ -3717,6 +3808,7 @@
4B35C5B40D4731D2000DE7AE /* jack_cpu 64 bits */,
4B35C5C00D4731D2000DE7AE /* jack_load 64 bits */,
4B35C5CC0D4731D2000DE7AE /* jack_unload 64 bits */,
4B0A29230D52108E002EFF74 /* jack_thread_wait 64 bits */,
4B35C5D80D4731D2000DE7AE /* synchroServer 64 bits */,
4B35C5EC0D4731D2000DE7AE /* synchroClient 64 bits */,
4B35C6000D4731D2000DE7AE /* synchroServerClient 64 bits */,
@@ -3774,6 +3866,20 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXRezBuildPhase section */
4B0A28E10D52073D002EFF74 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
4B0A29280D52108E002EFF74 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
4B35C4200D4731D1000DE7AE /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
@@ -4085,6 +4191,22 @@
/* End PBXRezBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
4B0A28DE0D52073D002EFF74 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4B0A28ED0D520852002EFF74 /* tw.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4B0A29250D52108E002EFF74 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4B0A29260D52108E002EFF74 /* tw.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4B35C41D0D4731D1000DE7AE /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -4742,6 +4864,16 @@
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
4B0A28F40D520D11002EFF74 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4B0A28DC0D52073D002EFF74 /* jack_thread_wait */;
targetProxy = 4B0A28F30D520D11002EFF74 /* PBXContainerItemProxy */;
};
4B0A29300D5210C4002EFF74 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4B0A29230D52108E002EFF74 /* jack_thread_wait 64 bits */;
targetProxy = 4B0A292F0D5210C4002EFF74 /* PBXContainerItemProxy */;
};
4B1C1AC00CC61597005F551E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4BE50F8D0B01EE8000C05E63 /* Jackwrapper.framework Universal */;
@@ -5020,6 +5152,192 @@
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
4B0A28E30D52073D002EFF74 /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
i386,
ppc,
);
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
HEADER_SEARCH_PATHS = ../common;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = (
"-framework",
Jackmp,
);
OTHER_REZFLAGS = "";
PRODUCT_NAME = jack_thread_wait;
REZ_EXECUTABLE = YES;
SDKROOT = "";
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = YES;
};
name = Development;
};
4B0A28E40D52073D002EFF74 /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
i386,
ppc,
);
COPY_PHASE_STRIP = YES;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_OPTIMIZATION_LEVEL = 3;
HEADER_SEARCH_PATHS = ../common;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = (
"-framework",
Jackmp,
);
OTHER_REZFLAGS = "";
PRODUCT_NAME = jack_thread_wait;
REZ_EXECUTABLE = YES;
SDKROOT = "";
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = NO;
};
name = Deployment;
};
4B0A28E50D52073D002EFF74 /* Default */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
i386,
ppc,
);
GCC_OPTIMIZATION_LEVEL = 3;
HEADER_SEARCH_PATHS = ../common;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = (
"-framework",
Jackmp,
);
OTHER_REZFLAGS = "";
PRODUCT_NAME = jack_thread_wait;
REZ_EXECUTABLE = YES;
SDKROOT = "";
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
};
name = Default;
};
4B0A292A0D52108E002EFF74 /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
i386,
ppc,
ppc64,
x86_64,
);
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
HEADER_SEARCH_PATHS = ../common;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = (
"-framework",
Jackmp,
);
OTHER_REZFLAGS = "";
PRODUCT_NAME = jack_thread_wait;
REZ_EXECUTABLE = YES;
SDKROOT = "";
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = YES;
};
name = Development;
};
4B0A292B0D52108E002EFF74 /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
i386,
ppc,
ppc64,
x86_64,
);
COPY_PHASE_STRIP = YES;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_OPTIMIZATION_LEVEL = 3;
HEADER_SEARCH_PATHS = ../common;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = (
"-framework",
Jackmp,
);
OTHER_REZFLAGS = "";
PRODUCT_NAME = jack_thread_wait;
REZ_EXECUTABLE = YES;
SDKROOT = "";
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = NO;
};
name = Deployment;
};
4B0A292C0D52108E002EFF74 /* Default */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
i386,
ppc,
ppc64,
x86_64,
);
GCC_OPTIMIZATION_LEVEL = 3;
HEADER_SEARCH_PATHS = ../common;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = (
"-framework",
Jackmp,
);
OTHER_REZFLAGS = "";
PRODUCT_NAME = jack_thread_wait;
REZ_EXECUTABLE = YES;
SDKROOT = "";
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
};
name = Default;
};
4B35C4220D4731D1000DE7AE /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -11193,6 +11511,26 @@
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
4B0A28E20D52073D002EFF74 /* Build configuration list for PBXNativeTarget "jack_thread_wait" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4B0A28E30D52073D002EFF74 /* Development */,
4B0A28E40D52073D002EFF74 /* Deployment */,
4B0A28E50D52073D002EFF74 /* Default */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default;
};
4B0A29290D52108E002EFF74 /* Build configuration list for PBXNativeTarget "jack_thread_wait 64 bits" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4B0A292A0D52108E002EFF74 /* Development */,
4B0A292B0D52108E002EFF74 /* Deployment */,
4B0A292C0D52108E002EFF74 /* Default */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default;
};
4B35C4210D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jackdmp framework 64bits" */ = {
isa = XCConfigurationList;
buildConfigurations = (


+ 7
- 0
windows/JackWinThread.cpp View File

@@ -247,5 +247,12 @@ pthread_t JackWinThread::GetThreadID()
return fThread;
}

void JackWinThread::Terminate()
{
TerminateThread(fThread, 0);
WaitForSingleObject(fThread, INFINITE);
CloseHandle(fThread);
}

} // end of namespace


+ 4
- 3
windows/JackWinThread.h View File

@@ -27,8 +27,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

namespace Jack
{
typedef DWORD (WINAPI *ThreadCallback)(void *arg);
typedef DWORD (WINAPI *ThreadCallback)(void *arg);

/*!
\brief Windows threads.
@@ -53,6 +53,7 @@ class JackWinThread : public JackThread
int StartSync();
int Kill();
int Stop();
void Terminate();

int AcquireRealTime();
int AcquireRealTime(int priority) ;
@@ -62,7 +63,7 @@ class JackWinThread : public JackThread
static int AcquireRealTimeImp(pthread_t thread, int priority);
static int DropRealTimeImp(pthread_t thread);
static int StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg);
static int StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg);

};



Loading…
Cancel
Save