Browse Source

Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver) in progress.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3498 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/v1.9.3
sletz 17 years ago
parent
commit
34ff05a8ca
27 changed files with 456 additions and 215 deletions
  1. +4
    -0
      ChangeLog
  2. +1
    -1
      common/JackAudioDriver.cpp
  3. +2
    -2
      common/JackClient.cpp
  4. +2
    -2
      common/JackConnectionManager.cpp
  5. +4
    -4
      common/JackConstants.h
  6. +21
    -0
      common/JackControlAPI.cpp
  7. +7
    -0
      common/JackControlAPI.h
  8. +42
    -2
      common/JackDriver.cpp
  9. +22
    -0
      common/JackDriver.h
  10. +3
    -2
      common/JackDriverLoader.cpp
  11. +6
    -0
      common/JackDriverLoader.h
  12. +2
    -5
      common/JackMidiDriver.cpp
  13. +2
    -3
      common/JackMidiDriver.h
  14. +3
    -3
      common/JackMidiPort.cpp
  15. +2
    -1
      common/JackMidiPort.h
  16. +36
    -26
      common/JackServer.cpp
  17. +4
    -2
      common/JackServer.h
  18. +13
    -0
      common/JackThreadedDriver.h
  19. +52
    -26
      common/Jackdmp.cpp
  20. +8
    -0
      common/jack/control.h
  21. +1
    -1
      common/wscript
  22. +12
    -8
      example-clients/midisine.c
  23. +84
    -13
      macosx/coremidi/JackCoreMidiDriver.cpp
  24. +1
    -3
      macosx/coremidi/JackCoreMidiDriver.h
  25. +17
    -0
      macosx/wscript
  26. +77
    -81
      windows/winmme/JackWinMMEDriver.cpp
  27. +28
    -30
      windows/winmme/JackWinMMEDriver.h

+ 4
- 0
ChangeLog View File

@@ -25,6 +25,10 @@ Paul Davis
Jackdmp changes log
---------------------------

2009-04-08 Stephane Letz <letz@grame.fr>

* Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver) in progress.

2009-04-03 Stephane Letz <letz@grame.fr>

* Simplify JackClient RT code, jack_thread_wait API marked deprecated."


+ 1
- 1
common/JackAudioDriver.cpp View File

@@ -1,6 +1,6 @@
/*
Copyright (C) 2001 Paul Davis
Copyright (C) 2004-2008 GramefClientControl.
Copyright (C) 2004-2008 Grame.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by


+ 2
- 2
common/JackClient.cpp View File

@@ -120,12 +120,12 @@ void JackClient::SetupDriverSync(bool freewheel)
jack_log("JackClient::SetupDriverSync driver sem in flush mode");
fSynchroTable[AUDIO_DRIVER_REFNUM].SetFlush(true);
fSynchroTable[FREEWHEEL_DRIVER_REFNUM].SetFlush(true);
fSynchroTable[LOOPBACK_DRIVER_REFNUM].SetFlush(true);
fSynchroTable[MIDI_DRIVER_REFNUM].SetFlush(true);
} else {
jack_log("JackClient::SetupDriverSync driver sem in normal mode");
fSynchroTable[AUDIO_DRIVER_REFNUM].SetFlush(false);
fSynchroTable[FREEWHEEL_DRIVER_REFNUM].SetFlush(false);
fSynchroTable[LOOPBACK_DRIVER_REFNUM].SetFlush(false);
fSynchroTable[MIDI_DRIVER_REFNUM].SetFlush(false);
}
}



+ 2
- 2
common/JackConnectionManager.cpp View File

@@ -58,8 +58,8 @@ bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const
|| ref2 == AUDIO_DRIVER_REFNUM
|| ref1 == FREEWHEEL_DRIVER_REFNUM
|| ref2 == FREEWHEEL_DRIVER_REFNUM
|| ref1 == LOOPBACK_DRIVER_REFNUM
|| ref2 == LOOPBACK_DRIVER_REFNUM) {
|| ref1 == MIDI_DRIVER_REFNUM
|| ref2 == MIDI_DRIVER_REFNUM) {
return false;
} else if (ref1 == ref2) { // Same refnum
return true;


+ 4
- 4
common/JackConstants.h View File

@@ -47,10 +47,10 @@
#define CLIENT_NUM 64
#endif

#define AUDIO_DRIVER_REFNUM 0 // Audio driver is initialized first, it will get the refnum 0
#define FREEWHEEL_DRIVER_REFNUM 1 // Freewheel driver is initialized second, it will get the refnum 1
#define LOOPBACK_DRIVER_REFNUM 2 // Loopback driver is initialized third, it will get the refnum 2
#define REAL_REFNUM LOOPBACK_DRIVER_REFNUM + 1 // Real clients start at LOOPBACK_DRIVER_REFNUM + 1
#define AUDIO_DRIVER_REFNUM 0 // Audio driver is initialized first, it will get the refnum 0
#define FREEWHEEL_DRIVER_REFNUM 1 // Freewheel driver is initialized second, it will get the refnum 1
#define MIDI_DRIVER_REFNUM 2 // Loopback driver is initialized third, it will get the refnum 2
#define REAL_REFNUM MIDI_DRIVER_REFNUM + 1 // Real clients start at MIDI_DRIVER_REFNUM + 1

#define JACK_DEFAULT_SERVER_NAME "default"



+ 21
- 0
common/JackControlAPI.cpp View File

@@ -42,6 +42,7 @@
#include "JackControlAPI.h"
#include "JackLockedEngine.h"
#include "JackConstants.h"
#include "JackDriverLoader.h"

using namespace Jack;

@@ -95,6 +96,7 @@ struct jackctl_driver
jack_driver_desc_t * desc_ptr;
JSList * parameters;
JSList * set_parameters;
JackDriverInfo* info;
};

struct jackctl_internal
@@ -1161,4 +1163,23 @@ EXPORT bool jackctl_server_unload_internal(
}
}

EXPORT bool jackctl_server_load_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
{
if (server_ptr->engine != NULL) {
driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters);
return (driver_ptr->info != 0);
} else {
return false;
}
}

EXPORT bool jackctl_server_unload_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
{
if (server_ptr->engine != NULL) {
server_ptr->engine->RemoveSlave(driver_ptr->info);
return true;
} else {
return false;
}
}


+ 7
- 0
common/JackControlAPI.h View File

@@ -219,6 +219,13 @@ EXPORT bool jackctl_server_load_internal(
EXPORT bool jackctl_server_unload_internal(
jackctl_server * server,
jackctl_internal * internal);
EXPORT bool jackctl_server_load_slave(jackctl_server_t * server,
jackctl_driver_t * driver);

EXPORT bool jackctl_server_unload_slave(jackctl_server_t * server,
jackctl_driver_t * driver);


#if 0
{ /* Adjust editor indent */


+ 42
- 2
common/JackDriver.cpp View File

@@ -68,7 +68,7 @@ int JackDriver::Open()
int refnum = -1;

if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
jack_error("Cannot allocate internal client for audio driver");
jack_error("Cannot allocate internal client for driver");
return -1;
}

@@ -79,6 +79,46 @@ int JackDriver::Open()
return 0;
}

int JackDriver::Open (bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
{
jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name);
jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name);
int refnum = -1;

if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
jack_error("Cannot allocate internal client for driver");
return -1;
}

fClientControl.fRefNum = refnum;
fClientControl.fActive = true;
fCaptureLatency = capture_latency;
fPlaybackLatency = playback_latency;

assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE);
assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE);

strcpy(fCaptureDriverName, capture_driver_name);
strcpy(fPlaybackDriverName, playback_driver_name);

fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec
if (!fEngineControl->fTimeOut)
fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);

//fGraphManager->SetBufferSize(fEngineControl->fBufferSize);
fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode
SetupDriverSync(fClientControl.fRefNum, false);
return 0;
}

int JackDriver::Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
@@ -96,7 +136,7 @@ int JackDriver::Open(jack_nframes_t buffer_size,
int refnum = -1;

if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) {
jack_error("Cannot allocate internal client for audio driver");
jack_error("Cannot allocate internal client for driver");
return -1;
}



+ 22
- 0
common/JackDriver.h View File

@@ -50,6 +50,17 @@ class SERVER_EXPORT JackDriverInterface
{}
virtual int Open() = 0;
virtual int Open (bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency) = 0;
virtual int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
@@ -142,6 +153,17 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
int ProcessSlaves();
virtual int Open();
virtual int Open (bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);
virtual int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,


+ 3
- 2
common/JackDriverLoader.cpp View File

@@ -800,7 +800,8 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver
jack_error("no initialize function in shared object %s\n", driver_desc->file);
return NULL;
}

return fInitialize(engine, synchro, params);
fBackend = fInitialize(engine, synchro, params);
return fBackend;
}


+ 6
- 0
common/JackDriverLoader.h View File

@@ -42,6 +42,7 @@ class JackDriverInfo
driverInitialize fInitialize;
DRIVER_HANDLE fHandle;
Jack::JackDriverClientInterface* fBackend;
public:
@@ -54,6 +55,11 @@ class JackDriverInfo
}
Jack::JackDriverClientInterface* Open(jack_driver_desc_t* driver_desc, Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*);
Jack::JackDriverClientInterface* GetBackend()
{
return fBackend;
}
};



+ 2
- 5
common/JackMidiDriver.cpp View File

@@ -24,7 +24,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackEngineControl.h"
#include "JackPort.h"
#include "JackGraphManager.h"
#include "JackLockedEngine.h"
#include "JackException.h"
#include <assert.h>

@@ -49,9 +48,7 @@ JackMidiDriver::~JackMidiDriver()
}
}

int JackMidiDriver::Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
int JackMidiDriver::Open(bool capturing,
bool playing,
int inchannels,
int outchannels,
@@ -68,7 +65,7 @@ int JackMidiDriver::Open(jack_nframes_t buffer_size,
fRingBuffer[i] = jack_ringbuffer_create(sizeof(float) * BUFFER_SIZE_MAX);
}
return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
}

int JackMidiDriver::Attach()


+ 2
- 3
common/JackMidiDriver.h View File

@@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include "JackDriver.h"
#include "JackMidiPort.h"
#include "JackLockedEngine.h"
#include "ringbuffer.h"

namespace Jack
@@ -52,9 +53,7 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver
JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table);
virtual ~JackMidiDriver();

virtual int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
virtual int Open(bool capturing,
bool playing,
int inchannels,
int outchannels,


+ 3
- 3
common/JackMidiPort.cpp View File

@@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
namespace Jack
{

void JackMidiBuffer::Reset(jack_nframes_t nframes)
SERVER_EXPORT void JackMidiBuffer::Reset(jack_nframes_t nframes)
{
/* This line ate 1 hour of my life... dsbaikov */
this->nframes = nframes;
@@ -37,7 +37,7 @@ void JackMidiBuffer::Reset(jack_nframes_t nframes)
mix_index = 0;
}

jack_shmsize_t JackMidiBuffer::MaxEventSize() const
SERVER_EXPORT jack_shmsize_t JackMidiBuffer::MaxEventSize() const
{
assert (((jack_shmsize_t) - 1) < 0); // jack_shmsize_t should be signed
jack_shmsize_t left = buffer_size - (sizeof(JackMidiBuffer) + sizeof(JackMidiEvent) * (event_count + 1) + write_pos);
@@ -48,7 +48,7 @@ jack_shmsize_t JackMidiBuffer::MaxEventSize() const
return left;
}

jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time, jack_shmsize_t size)
SERVER_EXPORT jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time, jack_shmsize_t size)
{
jack_shmsize_t space = MaxEventSize();
if (space == 0 || size > space) {


+ 2
- 1
common/JackMidiPort.h View File

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

#include "types.h"
#include "JackConstants.h"
#include "JackPlatformPlug.h"
#include <stddef.h>

/** Type for raw event data contained in @ref jack_midi_event_t. */
@@ -42,7 +43,7 @@ struct jack_midi_event_t
namespace Jack
{

struct JackMidiEvent
struct SERVER_EXPORT JackMidiEvent
{
// Most MIDI events are < 4 bytes in size, so we can save a lot, storing them inplace.
enum { INLINE_SIZE_MAX = sizeof(jack_shmsize_t) };


+ 36
- 26
common/JackServer.cpp View File

@@ -22,7 +22,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackServerGlobals.h"
#include "JackTime.h"
#include "JackFreewheelDriver.h"
#include "JackLoopbackDriver.h"
#ifdef __APPLE__
#include "macosx/coremidi/JackCoreMidiDriver.h"
#else
#include "JackMidiDriver.h"
#endif
#include "JackThreadedDriver.h"
#include "JackGlobals.h"
#include "JackLockedEngine.h"
@@ -50,10 +54,8 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr
fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, server_name);
fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl);
fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver(fEngine, GetSynchroTable()));
fLoopbackDriver = new JackLoopbackDriver(fEngine, GetSynchroTable());
fAudioDriver = NULL;
fFreewheel = false;
fLoopback = loopback;
JackServerGlobals::fInstance = this; // Unique instance
JackServerGlobals::fUserCount = 1; // One user
jack_verbose = verbose;
@@ -64,7 +66,6 @@ JackServer::~JackServer()
delete fGraphManager;
delete fAudioDriver;
delete fFreewheelDriver;
delete fLoopbackDriver;
delete fEngine;
delete fEngineControl;
}
@@ -94,35 +95,17 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params)
goto fail_close4;
}
if (fLoopbackDriver->Open(fEngineControl->fBufferSize, fEngineControl->fSampleRate, 1, 1, fLoopback, fLoopback, false, "loopback", "loopback", 0, 0) != 0) {
jack_error("Cannot open driver");
goto fail_close5;
}

if (fAudioDriver->Attach() != 0) {
jack_error("Cannot attach audio driver");
goto fail_close6;
}
if (fLoopback > 0 && fLoopbackDriver->Attach() != 0) {
jack_error("Cannot attach loopback driver");
goto fail_close7;
goto fail_close5;
}
fFreewheelDriver->SetMaster(false);
fAudioDriver->SetMaster(true);
if (fLoopback > 0)
fAudioDriver->AddSlave(fLoopbackDriver);
fAudioDriver->AddSlave(fFreewheelDriver); // After ???
InitTime();
return 0;

fail_close7:
fAudioDriver->Detach();
fail_close6:
fLoopbackDriver->Close();

fail_close5:
fFreewheelDriver->Close();

@@ -145,11 +128,8 @@ int JackServer::Close()
jack_log("JackServer::Close");
fChannel.Close();
fAudioDriver->Detach();
if (fLoopback > 0)
fLoopbackDriver->Detach();
fAudioDriver->Close();
fFreewheelDriver->Close();
fLoopbackDriver->Close();
fEngine->Close();
// TODO: move that in reworked JackServerGlobals::Destroy()
JackMessageBuffer::Destroy();
@@ -305,6 +285,36 @@ void JackServer::ClientKill(int refnum)
}
}

//----------------------
// Backend management
//----------------------

JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params)
{
JackDriverInfo* info = new JackDriverInfo();
JackDriverClientInterface* backend = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
if (backend == NULL) {
delete info;
return NULL;
} else {
//Stop();
backend->Attach();
fAudioDriver->AddSlave(backend);
//Start();
return info;
}
}

void JackServer::RemoveSlave(JackDriverInfo* info)
{
JackDriverClientInterface* backend = info->GetBackend();
//Stop();
fAudioDriver->RemoveSlave(info->GetBackend());
backend->Detach();
backend->Close();
//Start();
}

//----------------------
// Transport management
//----------------------


+ 4
- 2
common/JackServer.h View File

@@ -50,7 +50,6 @@ class SERVER_EXPORT JackServer
JackDriverInfo fDriverInfo;
JackDriverClientInterface* fAudioDriver;
JackDriverClientInterface* fFreewheelDriver;
JackDriverClientInterface* fLoopbackDriver;
JackLockedEngine* fEngine;
JackEngineControl* fEngineControl;
JackGraphManager* fGraphManager;
@@ -58,7 +57,6 @@ class SERVER_EXPORT JackServer
JackConnectionManager fConnectionState;
JackSynchro fSynchroTable[CLIENT_NUM];
bool fFreewheel;
long fLoopback;
int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int* status);

@@ -86,6 +84,10 @@ class SERVER_EXPORT JackServer
// Transport management
int ReleaseTimebase(int refnum);
int SetTimebaseCallback(int refnum, int conditional);
// Backend management
JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params);
void RemoveSlave(JackDriverInfo* info);

// Object access
JackLockedEngine* GetEngine();


+ 13
- 0
common/JackThreadedDriver.h View File

@@ -45,6 +45,19 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi
virtual ~JackThreadedDriver();

virtual int Open();
virtual int Open (bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
{
return -1;
}
virtual int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,


+ 52
- 26
common/Jackdmp.cpp View File

@@ -95,14 +95,14 @@ static void usage(FILE* file)
"usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n"
" [ --name OR -n server-name ]\n"
" [ --timeout OR -t client-timeout-in-msecs ]\n"
" [ --loopback OR -L loopback-port-number ]\n"
" [ --loopback OR -X midi-driver ]\n"
" [ --verbose OR -v ]\n"
" [ --replace-registry OR -r ]\n"
" [ --silent OR -s ]\n"
" [ --sync OR -S ]\n"
" [ --temporary OR -T ]\n"
" [ --version OR -V ]\n"
" -d driver [ ... driver args ... ]\n"
" -d audio-driver [ ... driver args ... ]\n"
" where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n"
" jackdmp -d driver --help\n"
" to display options for each driver\n\n");
@@ -154,10 +154,12 @@ int main(int argc, char* argv[])
jackctl_server_t * server_ctl;
const JSList * server_parameters;
const char* server_name = "default";
jackctl_driver_t * driver_ctl;
const char *options = "-ad:P:uvrshVRL:STFl:t:mn:p:";
jackctl_driver_t * audio_driver_ctl;
jackctl_driver_t * midi_driver_ctl;
const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:";
struct option long_options[] = {
{ "driver", 1, 0, 'd' },
{ "audio-driver", 1, 0, 'd' },
{ "midi-driver", 1, 0, 'X' },
{ "verbose", 0, 0, 'v' },
{ "help", 0, 0, 'h' },
{ "port-max", 1, 0, 'p' },
@@ -177,10 +179,14 @@ int main(int argc, char* argv[])
};
int i,opt = 0;
int option_index = 0;
bool seen_driver = false;
char *driver_name = NULL;
char **driver_args = NULL;
int driver_nargs = 1;
bool seen_audio_driver = false;
bool seen_midi_driver = false;
char *audio_driver_name = NULL;
char **audio_driver_args = NULL;
int audio_driver_nargs = 1;
char *midi_driver_name = NULL;
char **midi_driver_args = NULL;
int midi_driver_nargs = 1;
int port_max = 512;
int do_mlock = 1;
int do_unlock = 0;
@@ -200,14 +206,19 @@ int main(int argc, char* argv[])
server_parameters = jackctl_server_get_parameters(server_ctl);

opterr = 0;
while (!seen_driver &&
while (!seen_audio_driver &&
(opt = getopt_long(argc, argv, options,
long_options, &option_index)) != EOF) {
switch (opt) {

case 'd':
seen_driver = true;
driver_name = optarg;
seen_audio_driver = true;
audio_driver_name = optarg;
break;
case 'X':
seen_midi_driver = true;
midi_driver_name = optarg;
break;
case 'p':
@@ -306,6 +317,7 @@ int main(int argc, char* argv[])
default:
fprintf(stderr, "unknown option character %c\n", optopt);
/*fallthru*/
case 'h':
usage(stdout);
goto fail_free;
@@ -320,45 +332,59 @@ int main(int argc, char* argv[])
return -1;
}
if (!seen_driver) {
if (!seen_audio_driver) {
usage(stderr);
goto fail_free;
}

driver_ctl = jackctl_server_get_driver(server_ctl, driver_name);
if (driver_ctl == NULL) {
fprintf(stderr, "Unkown driver \"%s\"\n", driver_name);
// Audio driver
audio_driver_ctl = jackctl_server_get_driver(server_ctl, audio_driver_name);
if (audio_driver_ctl == NULL) {
fprintf(stderr, "Unkown driver \"%s\"\n", audio_driver_name);
goto fail_free;
}

if (optind < argc) {
driver_nargs = 1 + argc - optind;
audio_driver_nargs = 1 + argc - optind;
} else {
driver_nargs = 1;
audio_driver_nargs = 1;
}

if (driver_nargs == 0) {
if (audio_driver_nargs == 0) {
fprintf(stderr, "No driver specified ... hmm. JACK won't do"
" anything when run like this.\n");
goto fail_free;
}

driver_args = (char **) malloc(sizeof(char *) * driver_nargs);
driver_args[0] = driver_name;
audio_driver_args = (char **) malloc(sizeof(char *) * audio_driver_nargs);
audio_driver_args[0] = audio_driver_name;

for (i = 1; i < driver_nargs; i++) {
driver_args[i] = argv[optind++];
for (i = 1; i < audio_driver_nargs; i++) {
audio_driver_args[i] = argv[optind++];
}

if (jackctl_parse_driver_params(driver_ctl, driver_nargs, driver_args)) {
if (jackctl_parse_driver_params(audio_driver_ctl, audio_driver_nargs, audio_driver_args)) {
goto fail_free;
}
if (!jackctl_server_start(server_ctl, driver_ctl)) {
// Start server
if (!jackctl_server_start(server_ctl, audio_driver_ctl)) {
fprintf(stderr, "Failed to start server\n");
goto fail_free;
}
// MIDI driver
if (seen_midi_driver) {
midi_driver_ctl = jackctl_server_get_driver(server_ctl, midi_driver_name);
if (midi_driver_ctl == NULL) {
fprintf(stderr, "Unkown driver \"%s\"\n", midi_driver_name);
goto fail_free;
}
jackctl_server_load_slave(server_ctl, midi_driver_ctl);
}

notify_server_start(server_name);

// Waits for signal


+ 8
- 0
common/jack/control.h View File

@@ -510,6 +510,14 @@ jack_log(

/* @} */

bool
jackctl_server_load_slave(jackctl_server_t * server,
jackctl_driver_t * driver);

bool
jackctl_server_unload_slave(jackctl_server_t * server,
jackctl_driver_t * driver);

#if 0
{ /* Adjust editor indent */
#endif


+ 1
- 1
common/wscript View File

@@ -171,7 +171,7 @@ def build(bld):
serverlib.env.append_value("CPPFLAGS", "-fvisibility=hidden")
serverlib.env.append_value("CPPFLAGS", "-mmacosx-version-min=10.4 -arch i386 -arch ppc")
#serverlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module -arch i386 -arch ppc")
serverlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module")
serverlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework CoreFoundation -framework vecLib -single_module")
serverlib.env.append_value("LINKFLAGS", "-compatibility_version 1 -current_version 1")

if bld.env['IS_SUN']:


+ 12
- 8
example-clients/midisine.c View File

@@ -71,17 +71,21 @@ static int process(jack_nframes_t nframes, void *arg)
/* printf("1st byte of 1st event addr is %p\n", in_events[0].buffer);*/
}
jack_midi_event_get(&in_event, port_buf, 0);
for(i=0; i<nframes; i++)
for(i = 0; i < nframes; i++)
{
if((in_event.time == i) && (event_index < event_count))
if ((in_event.time == i) && (event_index < event_count))
{
if( ((*(in_event.buffer) & 0xf0)) == 0x90 )
{
/* note on */
note = *(in_event.buffer + 1);
note_on = 1.0;
if (((*(in_event.buffer) & 0xf0)) == 0x90)
{
/* note on */
note = *(in_event.buffer + 1);
if (*(in_event.buffer + 2) == 0) {
note_on = 0.0;
} else {
note_on = (float)(*(in_event.buffer + 2)) / 127.f;
}
}
else if( ((*(in_event.buffer)) & 0xf0) == 0x80 )
else if (((*(in_event.buffer)) & 0xf0) == 0x80)
{
/* note off */
note = *(in_event.buffer + 1);


+ 84
- 13
macosx/coremidi/JackCoreMidiDriver.cpp View File

@@ -19,7 +19,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include "JackCoreMidiDriver.h"
#include "JackGraphManager.h"
#include "JackServer.h"
#include "JackEngineControl.h"
#include "JackDriverLoader.h"

#include <mach/mach_time.h>
#include <assert.h>
#include <iostream>
@@ -90,18 +93,16 @@ JackCoreMidiDriver::JackCoreMidiDriver(const char* name, const char* alias, Jack
JackCoreMidiDriver::~JackCoreMidiDriver()
{}

int JackCoreMidiDriver::Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
{
int JackCoreMidiDriver::Open(bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
{
OSStatus err;
CFStringRef coutputStr;
std::string str;
@@ -111,7 +112,7 @@ int JackCoreMidiDriver::Open(jack_nframes_t buffer_size,
fRealPlaybackChannels = MIDIGetNumberOfDestinations();
// Generic JackMidiDriver Open
if (JackMidiDriver::Open(buffer_size, samplerate, capturing, playing, inchannels + fRealCaptureChannels, outchannels + fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0)
if (JackMidiDriver::Open(capturing, playing, inchannels + fRealCaptureChannels, outchannels + fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0)
return -1;
coutputStr = CFStringCreateWithCString(0, "JackMidi", CFStringGetSystemEncoding());
@@ -352,4 +353,74 @@ int JackCoreMidiDriver::Write()

} // end of namespace

#ifdef __cplusplus
extern "C"
{
#endif

SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor()
{
jack_driver_desc_t * desc;
unsigned int i;

desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t));
strcpy(desc->name, "coremidi"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
strcpy(desc->desc, "Apple CoreMIDI API based MIDI backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1

desc->nparams = 2;
desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
i = 0;
strcpy(desc->params[i].name, "inchannels");
desc->params[i].character = 'i';
desc->params[i].type = JackDriverParamInt;
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "CoreMIDI virtual bus");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);

i++;
strcpy(desc->params[i].name, "outchannels");
desc->params[i].character = 'o';
desc->params[i].type = JackDriverParamInt;
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "CoreMIDI virtual bus");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);

return desc;
}

SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
{
const JSList * node;
const jack_driver_param_t * param;
int virtual_in = 0;
int virtual_out = 0;

for (node = params; node; node = jack_slist_next (node)) {
param = (const jack_driver_param_t *) node->data;

switch (param->character) {

case 'i':
virtual_in = param->value.ui;
break;

case 'o':
virtual_out = param->value.ui;
break;
}
}
Jack::JackDriverClientInterface* driver = new Jack::JackCoreMidiDriver("system_midi", "coremidi", engine, table);
if (driver->Open(1, 1, virtual_in, virtual_out, false, "in", "out", 0, 0) == 0) {
return driver;
} else {
delete driver;
return NULL;
}
}

#ifdef __cplusplus
}
#endif


+ 1
- 3
macosx/coremidi/JackCoreMidiDriver.h View File

@@ -57,9 +57,7 @@ class JackCoreMidiDriver : public JackMidiDriver
JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table);
virtual ~JackCoreMidiDriver();

int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
int Open( bool capturing,
bool playing,
int chan_in,
int chan_out,


+ 17
- 0
macosx/wscript View File

@@ -30,6 +30,21 @@ def create_jack_audio_driver_obj(bld, target, sources, uselib = None):
driver.uselib = uselib
return driver

def create_jack_midi_driver_obj(bld, target, sources, uselib = None):
driver = bld.new_task_gen('cxx', 'shlib')
driver.features.append('cc')
driver.env['shlib_PATTERN'] = 'jack_%s.so'
driver.defines = 'HAVE_CONFIG_H'
driver.includes = ['.', '../macosx', '../posix', '../common', '../common/jack']
driver.target = target
driver.source = sources
driver.install_path = '${ADDON_DIR}/'
driver.uselib_local = 'serverlib'
driver.env.append_value("LINKFLAGS", "-framework CoreMIDI -framework CoreServices -framework AudioUnit")
if uselib:
driver.uselib = uselib
return driver

def build(bld):
jackd = bld.new_task_gen('cxx', 'program')
jackd.includes = ['.', '../macosx', '../posix', '../common', '../common/jack']
@@ -43,6 +58,8 @@ def build(bld):
create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp')

create_jack_audio_driver_obj(bld, 'coreaudio', 'coreaudio/JackCoreAudioDriver.cpp')

create_jack_midi_driver_obj(bld, 'coremidi', 'coremidi/JackCoreMidiDriver.cpp')
portaudio_src = [
'../windows/JackPortAudioDriver.cpp',


+ 77
- 81
windows/winmme/JackWinMMEDriver.cpp View File

@@ -1,37 +1,37 @@
/*
Copyright (C) 2009 Grame
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "JackWinMMEDriver.h"
#include "JackGraphManager.h"
/*
Copyright (C) 2009 Grame
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "JackWinMMEDriver.h"
#include "JackGraphManager.h"
#include "JackEngineControl.h"
#include "JackDriverLoader.h"
#include <assert.h>
#include <iostream>
#include <sstream>
#include <assert.h>
#include <iostream>
#include <sstream>
#include <string>
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
namespace Jack
#include <mmsystem.h>
namespace Jack
{
static bool InitHeaders(MidiSlot* slot)
@@ -80,29 +80,29 @@ void CALLBACK JackWinMMEDriver::MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD use
break;
}
}
JackWinMMEDriver::JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
JackWinMMEDriver::JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
: JackMidiDriver(name, alias, engine, table),
fRealCaptureChannels(0),
fRealPlaybackChannels(0),
fMidiSource(NULL),
fMidiDestination(NULL)
{}
JackWinMMEDriver::~JackWinMMEDriver()
{}
int JackWinMMEDriver::Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
fMidiDestination(NULL)
{}
JackWinMMEDriver::~JackWinMMEDriver()
{}
int JackWinMMEDriver::Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
{
jack_log("JackWinMMEDriver::Open");
@@ -190,12 +190,12 @@ int JackWinMMEDriver::Open(jack_nframes_t buffer_size,
goto error;
}
}
return 0;
error:
Close();
return -1;
return 0;
error:
Close();
return -1;
}
void JackWinMMEDriver::CloseInput(MidiSlot* slot)
@@ -260,9 +260,9 @@ void JackWinMMEDriver::CloseOutput(MidiSlot* slot)
if (slot->fHeader) {
GlobalFreePtr(slot->fHeader);
}
}
int JackWinMMEDriver::Close()
}
int JackWinMMEDriver::Close()
{
jack_log("JackWinMMEDriver::Close");
@@ -281,9 +281,9 @@ int JackWinMMEDriver::Close()
}
delete[] fMidiSource;
}
return 0;
}
return 0;
}
int JackWinMMEDriver::Attach()
{
@@ -341,8 +341,8 @@ int JackWinMMEDriver::Attach()
return 0;
}
int JackWinMMEDriver::Read()
int JackWinMMEDriver::Read()
{
size_t size;
@@ -377,11 +377,11 @@ int JackWinMMEDriver::Read()
//jack_info("Consume ring buffer");
jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan]));
}
}
return 0;
}
int JackWinMMEDriver::Write()
}
return 0;
}
int JackWinMMEDriver::Write()
{
for (int chan = 0; chan < fPlaybackChannels; chan++) {
@@ -403,10 +403,10 @@ int JackWinMMEDriver::Write()
}
}
}
return 0;
}
return 0;
}
} // end of namespace
#ifdef __cplusplus
@@ -414,7 +414,8 @@ extern "C"
{
#endif
SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor () {
SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor()
{
jack_driver_desc_t * desc;
unsigned int i;
@@ -428,11 +429,8 @@ extern "C"
return desc;
}
SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) {
jack_nframes_t sample_rate = 48000;
jack_nframes_t period_size = 1024;
SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
{
/*
unsigned int capture_ports = 2;
unsigned int playback_ports = 2;
@@ -474,7 +472,7 @@ extern "C"
*/
Jack::JackDriverClientInterface* driver = new Jack::JackWinMMEDriver("system_midi", "winmme", engine, table);
if (driver->Open(period_size, sample_rate, 1, 1, 0, 0, false, "in", "out", 0, 0) == 0) {
if (driver->Open(1, 1, 0, 0, false, "in", "out", 0, 0) == 0) {
return driver;
} else {
delete driver;
@@ -485,8 +483,8 @@ extern "C"
#ifdef __cplusplus
}
#endif
/*
jack_connect system:midi_capture_1 system_midi:playback_1
jack_connect system:midi_capture_1 system_midi:playback_2
@@ -500,8 +498,6 @@ jack_connect system:midi_capture_1 system_midi:playback_1
jack_connect system_midi:capture_1 system:midi_playback_1
jack_connect system_midi:capture_2 system:midi_playback_1
jack_connect system_midi:capture_1 system_midi:playback_1
*/

+ 28
- 30
windows/winmme/JackWinMMEDriver.h View File

@@ -28,35 +28,35 @@ namespace Jack

/*!
\brief The WinMME driver.
*/
#define kBuffSize 512
struct MidiSlot {
LPVOID fHandle; // MMSystem handler
short fIndex; // MMSystem dev index
LPMIDIHDR fHeader; // for long msg output
MidiSlot():fHandle(0),fIndex(0)
{}
};
*/
#define kBuffSize 512
struct MidiSlot {
LPVOID fHandle; // MMSystem handler
short fIndex; // MMSystem dev index
LPMIDIHDR fHeader; // for long msg output
MidiSlot():fHandle(0),fIndex(0)
{}
};

class JackWinMMEDriver : public JackMidiDriver
{

private:
int fRealCaptureChannels;
int fRealPlaybackChannels;
MidiSlot* fMidiSource;
MidiSlot* fMidiDestination;
void CloseInput(MidiSlot* slot);
void CloseOutput(MidiSlot* slot);
private:
int fRealCaptureChannels;
int fRealPlaybackChannels;
MidiSlot* fMidiSource;
MidiSlot* fMidiDestination;
void CloseInput(MidiSlot* slot);
void CloseOutput(MidiSlot* slot);
static void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);

public:
@@ -64,9 +64,7 @@ class JackWinMMEDriver : public JackMidiDriver
JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table);
virtual ~JackWinMMEDriver();

int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
int Open(bool capturing,
bool playing,
int chan_in,
int chan_out,
@@ -75,8 +73,8 @@ class JackWinMMEDriver : public JackMidiDriver
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);
int Close();
int Close();
int Attach();

int Read();


Loading…
Cancel
Save