Browse Source

Merge commit '1.9.9.5' into no-self-connect

Conflicts:
	common/JackControlAPI.cpp
tags/v1.9.10
Nedko Arnaudov 12 years ago
parent
commit
760e5477a4
87 changed files with 1622 additions and 593 deletions
  1. +87
    -1
      ChangeLog
  2. +1
    -0
      README
  3. +15
    -23
      common/JackAudioAdapterFactory.cpp
  4. +1
    -1
      common/JackConstants.h
  5. +100
    -70
      common/JackControlAPI.cpp
  6. +18
    -2
      common/JackEngine.cpp
  7. +0
    -3
      common/JackInternalClient.cpp
  8. +2
    -2
      common/JackLibAPI.cpp
  9. +5
    -5
      common/JackLockedEngine.h
  10. +3
    -10
      common/JackMidiDriver.cpp
  11. +6
    -1
      common/JackNetAPI.cpp
  12. +15
    -2
      common/JackNetAdapter.cpp
  13. +16
    -3
      common/JackNetDriver.cpp
  14. +1
    -1
      common/JackNetDriver.h
  15. +4
    -0
      common/JackNetInterface.cpp
  16. +1
    -1
      common/JackNetManager.cpp
  17. +165
    -0
      common/JackNetOneDriver.cpp
  18. +6
    -0
      common/JackNetOneDriver.h
  19. +234
    -0
      common/JackNetTool.cpp
  20. +60
    -11
      common/JackNetTool.h
  21. +2
    -2
      common/JackPort.h
  22. +2
    -2
      common/JackRequestDecoder.cpp
  23. +1
    -1
      common/JackServer.cpp
  24. +1
    -1
      common/JackServerAPI.cpp
  25. +0
    -10
      common/JackServerGlobals.cpp
  26. +0
    -10
      common/Jackdmp.cpp
  27. +1
    -1
      common/jack/intclient.h
  28. +4
    -4
      common/jack/jack.h
  29. +1
    -0
      common/jack/net.h
  30. +45
    -1
      common/netjack.c
  31. +8
    -0
      common/netjack.h
  32. +100
    -0
      common/netjack_packet.c
  33. +1
    -0
      common/netjack_packet.h
  34. +23
    -9
      common/shm.c
  35. +34
    -1
      common/shm.h
  36. +3
    -3
      common/wscript
  37. +3
    -0
      dbus/audio_reserve.c
  38. +3
    -0
      dbus/controller.c
  39. +62
    -18
      dbus/reserve.c
  40. +5
    -1
      dbus/sigsegv.c
  41. +1
    -1
      dbus/wscript
  42. +2
    -2
      example-clients/control.c
  43. +39
    -1
      example-clients/jack_control
  44. +1
    -1
      example-clients/metro.c
  45. +1
    -1
      example-clients/netmaster.c
  46. +44
    -3
      example-clients/netsource.c
  47. +2
    -1
      example-clients/server_control.cpp
  48. +1
    -1
      example-clients/simple_client.c
  49. +2
    -2
      example-clients/tw.c
  50. +13
    -14
      example-clients/wscript
  51. +6
    -0
      linux/alsa/JackAlsaAdapter.cpp
  52. +10
    -3
      linux/alsa/JackAlsaAdapter.h
  53. +47
    -36
      linux/alsa/JackAlsaDriver.cpp
  54. +1
    -3
      linux/alsa/JackAlsaDriver.h
  55. +3
    -17
      linux/alsa/alsa_driver.c
  56. +2
    -2
      linux/wscript
  57. +2
    -2
      macosx/Jack-Info.plist
  58. +11
    -7
      macosx/Jackdmp.xcodeproj/project.pbxproj
  59. +12
    -2
      macosx/coreaudio/JackCoreAudioAdapter.cpp
  60. +69
    -56
      macosx/coreaudio/JackCoreAudioDriver.cpp
  61. +2
    -1
      macosx/coreaudio/TiPhoneCoreAudioRenderer.h
  62. +6
    -5
      macosx/coremidi/JackCoreMidiOutputPort.cpp
  63. +20
    -10
      macosx/install_jackdmp
  64. +3
    -7
      macosx/remove_jackdmp
  65. +5
    -2
      posix/JackPosixServerLaunch.cpp
  66. +1
    -1
      posix/JackSocketServerChannel.cpp
  67. +1
    -1
      solaris/wscript
  68. +100
    -88
      tests/iodelay.cpp
  69. +1
    -1
      windows/JackWinNamedPipeServerChannel.cpp
  70. +0
    -3
      windows/JackWinNamedPipeServerChannel.h
  71. +4
    -4
      windows/jackaudioadapter.rc
  72. +4
    -4
      windows/jackd.rc
  73. +4
    -4
      windows/jackdummydriver.rc
  74. +4
    -4
      windows/jackloopbackdriver.rc
  75. +4
    -4
      windows/jacknetadapter.rc
  76. +4
    -4
      windows/jacknetdriver.rc
  77. +4
    -4
      windows/jacknetmanager.rc
  78. +4
    -4
      windows/jacknetonedriver.rc
  79. +4
    -4
      windows/jackportaudio.rc
  80. +4
    -4
      windows/jackwinmme.rc
  81. +4
    -4
      windows/libjack.rc
  82. +4
    -4
      windows/libjacknet.rc
  83. +4
    -4
      windows/libjackserver.rc
  84. +56
    -31
      windows/portaudio/JackPortAudioDevices.cpp
  85. +1
    -0
      windows/portaudio/JackPortAudioDevices.h
  86. +27
    -26
      windows/portaudio/JackPortAudioDriver.cpp
  87. +39
    -10
      wscript

+ 87
- 1
ChangeLog View File

@@ -31,11 +31,97 @@ David Garcia Garzon
Valerio Pilo
Chris Caudle
John Emmas
Robin Gareus

---------------------------
Jackdmp changes log
---------------------------

2012-11-21 Stephane Letz <letz@grame.fr>

* Correct JackPortAudioDriver::Open : special case for ASIO drivers.

2012-10-20 Stephane Letz <letz@grame.fr>

* Correct JackEngine::NotifyGraphReorder : graph-order callback now notified after port latencies update.

2012-09-22 Robin Gareus <robin@gareus.org>

* netjack/opus: don't re-init en/decoders.

2012-09-18 Nedko Arnaudov <nedko@arnaudov.name>

* Use string ids in the alsa device list.

2012-09-10 Nedko Arnaudov <nedko@arnaudov.name>

* controlapi: fix double free on master switch.

2012-09-10 Robin Gareus <robin@gareus.org>

* netjack1/netone opus support.
* netjack1/2 Opus: use only 2bytes for encoded-length.
* wscript: add header defines and libs for example-clients/netsource.
* fix duplicate prog.includes.

2012-09-05 Stephane Letz <letz@grame.fr>

* More robust channel mapping handling in JackCoreAudioDriver.

2012-09-05 Robin Gareus <robin@gareus.org>

* Add opus support to NetJack2.

2012-08-21 Nedko Arnaudov <nedko@arnaudov.name>

* jack_control: fix epr command.

2012-08-21 Stephane Letz <letz@grame.fr>

* Update JackCoreAudioDriver and JackCoreAudioAdapter with more recent API.

2012-08-03 Stephane Letz <letz@grame.fr>

* Change framework installation hierarchy for OSX Mountain Lion.

2012-08-02 Stephane Letz <letz@grame.fr>

* Devin Anderson patch for Jack/CoreMIDI duplicated messages.

2012-07-24 Stephane Letz <letz@grame.fr>

* Fix in ALSA adapter.

2012-05-26 Nedko Arnaudov <nedko@arnaudov.name>

* Fix alsa driver parameter order.
* Control API: Enforce driver/internal parameter order.

2012-05-24 Nedko Arnaudov <nedko@arnaudov.name>

* Extend jack_control to have parameter reset commands.

2012-03-24 Adrian Knoth <adi@drcomp.erfurt.thur.de>

* Align buffers to 32 byte boundaries to allow AVX processing.

2012-03-21 Stephane Letz <letz@grame.fr>

* New jack_get_cycle_times() implementation from Fons Adriennsen.

2012-03-17 Nedko Arnaudov <nedko@arnaudov.name>

* Update waf.

2012-03-17 Adrian Knoth <adi@drcomp.erfurt.thur.de>

* [firewire] Introduce UpdateLatencies() in FFADO backend.
* [firewire] Allow FFADO backend to change the buffer size.

2012-03-16 Stephane Letz <letz@grame.fr>

* Rework JackMessageBuffer.

2012-03-15 Stephane Letz <letz@grame.fr>

* POST_PACKED_STRUCTURE used for jack_latency_range_t type.
@@ -81,7 +167,7 @@ John Emmas

2012-01-20 Stephane Letz <letz@grame.fr>

* Experimental system port alias use in WIndows JackRouter.
* Experimental system port alias use in Windows JackRouter.

2012-01-19 Stephane Letz <letz@grame.fr>



+ 1
- 0
README View File

@@ -214,6 +214,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console.
1.9.6 : Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them.Correct JackGraphManager::DeactivatePort. Correct JackMachServerChannel::Execute : keep running even in error cases. Raise JACK_PROTOCOL_VERSION number. Arnold Krille firewire patch. Raise JACK_DRIVER_PARAM_STRING_MAX and JACK_PARAM_STRING_MAX to 127 otherwise some audio drivers cannot be loaded on OSX. Fix some file header to have library side code use LGPL. On Windows, now use TRE library for regexp (BSD license instead of GPL license). ffado-portname-sync.patch from ticket #163 applied. Remove call to exit in library code. Make jack_connect/jack_disconnect wait for effective port connection/disconnection. Add tests to validate intclient.h API. On Linux, inter-process synchronization primitive switched to POSIX semaphore. In JackCoreAudioDriver, move code called in MeasureCallback to be called once in IO thread. David Garcia Garzon netone patch. Fix from Fernando Lopez-Lezcano for compilation on fc13. Fix JackPosixSemaphore::TimedWait : same behavior as JackPosixSemaphore::Wait regarding EINTR. David Garcia Garzon unused_pkt_buf_field_jack2 netone patch. Arnold Krille firewire snooping patch. Jan Engelhardt patch for get_cycles on SPARC. Adrian Knoth hurd.patch, kfreebsd-fix.patch and alpha_ia64-sigsegv.patch from ticket 177. Adrian Knoth fix for linux cycle.h (ticket 188). In JackCoreAudioDriver, fix an issue when no value is given for input.
1.9.7 : Sync JackAlsaDriver::alsa_driver_check_card_type with JACK1 backend. Correct JackServer::Open to avoid a race when control API is used on OSX. Improve backend error handling: fatal error returned by Read/Write now cause a Process failure (so a thread exit for blocking backends). Recoverable ones (XRuns..) are now treated internally in ALSA, FreeBob and FFADO backends. In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start. Correct symbols export in backends on OSX. ALSA backend : suspend/resume handling. Correct dummy driver. Adrian Knoth jack_lsp patch. Remove JackPortIsActive flag. New latency API implementation. ComputeTotalLatencies now a client/server call. Add latent test client for latency API. Also print playback and capture latency in jack_lsp. jack_client_has_session_callback implementation. Check requested buffer size and limit to 1..8192 - avoids weird behaviour caused by jack_bufsize foobar. jack_port_type_get_buffer_size implementation. Stop using alloca and allocate buffer on the heap for alsa_io. Rename jdelay to jack_iodelay as per Fons' request. Call buffer size callback in activate (actually this is done on client side in the RT thread Init method). Add jack_midi_dump client. Synchronize net JACK1 with JACK1 version. Synchronize jack_connect/jack_disconnect with JACK1 version. Correct JackNetMaster::SetBufferSize. Use jack_default_audio_sample_t instead of float consistently, fix ticket #201. -X now allows to add several slave backends, add -I to load several internal clients. Rework internal slave driver management, JackServerGlobals now handle same parameters as jackdmp. Correct JackEngine::NotifyGraphReorder, update JackDebugClient with latest API. Devin Anderson server-ctl-proposal branch merged on trunk: improved control API, slave backend reworked. Implement renaming in JackDriver::Open to avoid name collision (thanks Devin Anderson). Correct alsa_driver_restart (thanks Devin Anderson). Correction of jack_connect/jack_disconnect: use of jack_activate and volatile keyword for thread shared variable. Correction of JackNetOneDriver for latest CELT API. Synchronize JackWeakAPI.cpp with new APIs.
1.9.8 : Merge newer-midi branch (Devin Anderson redesign of the MIDI drivers: alsarawmidi, ffado, coremidi and winmme). Correction in jackdmp.cpp: notify_server_stop should be done after server destruction. Correct driver lifetime management. Add XRun detection in PortAudio driver. CELT code for NetJack2. Merge branch switch-master-port-registration-notifications: correct driver port registration. Libjacknet in progress. Correct MIDI in NetJack2. Correct OSX real-time thread setup. Correct rd_acquire in dbus code. Correct NetJack2 connection handling. SaveConnections/RestoreConnections in NetDriver and JackAudioDriver. Special version of jack_attach_shm/jack_release_shm on client side for POSIX shared memory, to solve a memory leak issue. Another round of code improvements to handle completely buggy Digidesign CoreAudio user-land driver. Special CATCH_CLOSE_EXCEPTION_RETURN to handle Close API calls. Add JACK_NETJACK_PORT and JACK_NETJACK_MULTICAST environment variables for NetJack2. NetJack2 now only send data on network only is ports are connected both sides. Fix for "starting two instances of same app in parallel does not work" bug. Enable explicit channel mapping in CoreAudio driver. New JackTimedDriver class to be used by JackDummyDriver, JackNetDriver and JackNetOneDriver classes. More robust code in synchronization primitives and in JackMessageBuffer. More robust Control API implementation. Add jackctl_driver_get_type in Control API. Singleton behaviour for JackCoreMidiDriver and JackWinMMEDriver. John Emmas patch for DSP CPU computation. John Emmas Windows server launching patch. Fix jack_set_port_name API. Enable local access in NetJack2 code. Dynamic port management in JACK/CoreMidi bridge.
1.9.9 : Adrian Knoth fix in midiseq.c. Fix library symbols export issue. Cleanup drivers and internals loading code. jackctl_driver_params_parse API moved in public control.h. More general drivers/internals loading model on Windows. Factorize code the server/client request in JackRequestDecoder class. More robust server/client protocol. Implement shutdown for in server clients. Better time-out management in NetJack2. Experimental system port alias use in Windows JackRouter. Improve ShutDown in NetManager. Correct ShutDown in JackInternalClient and JackLibClient. Fix NetJack2 initialisation bug. Add EndTime function (especially for Windows). Rename JackProcessSync in JackPosixProcessSync. A bit more robust JackMessageBuffer implementation (in progress). Check server API callback from notification thread. Use a time-out in notification channel write function. Fix lock management in JackEngine. In control API, UNIX like sigset_t replaced by more abstract jackctl_sigmask_t * opaque struct. Improve libjacknet master mode. Remove JACK_32_64 flag, so POST_PACKED_STRUCTURE now always used. POST_PACKED_STRUCTURE used for jack_latency_range_t type. Rework JackMessageBuffer. [firewire] Introduce UpdateLatencies() in FFADO backend. [firewire] Allow FFADO backend to change the buffer size. Update waf. New jack_get_cycle_times() implementation from Fons Adriennsen. Align buffers to 32 byte boundaries to allow AVX processing. Extend jack_control to have parameter reset commands. Fix alsa driver parameter order. Control API: Enforce driver/internal parameter order. Fix in ALSA adapter. Devin Anderson patch for Jack/CoreMIDI duplicated messages. Change framework installation hierarchy for OSX Mountain Lion. Update JackCoreAudioDriver and JackCoreAudioAdapter with more recent API. jack_control: fix epr command. Add opus support to NetJack2. More robust channel mapping handling in JackCoreAudioDriver. netjack1/netone opus support. controlapi: fix double free on master switch. Use string ids in the alsa device list. netjack/opus: don't re-init en/decoders. Correct JackPortAudioDriver::Open : special case for ASIO drivers.
This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, QjackCtl, Jack-Rack, SooperLooper, AlsaPlayer...


+ 15
- 23
common/JackAudioAdapterFactory.cpp View File

@@ -1,5 +1,5 @@
/*
Copyright (C) 2008 Grame
Copyright (C) 2008-2012 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
@@ -18,25 +18,31 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "JackAudioAdapter.h"
#include "JackPlatformPlug.h"
#include "JackArgParser.h"

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#ifdef __linux__
#include "JackAlsaAdapter.h"
#endif

#ifdef __APPLE__
#include "JackCoreAudioAdapter.h"
#define JackPlatformAdapter JackCoreAudioAdapter
#endif

#ifdef WIN32
#include "JackPortAudioAdapter.h"
#ifdef __linux__
#include "JackAlsaAdapter.h"
#define JackPlatformAdapter JackAlsaAdapter
#endif

#if defined(__sun__) || defined(sun)
#include "JackOSSAdapter.h"
#define JackPlatformAdapter JackOSSAdapter
#endif

#ifdef WIN32
#include "JackPortAudioAdapter.h"
#define JackPlatformAdapter JackPortAudioAdapter
#endif

#ifdef __cplusplus
@@ -56,22 +62,7 @@ extern "C"

try {

#ifdef __linux__
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackAlsaAdapter(buffer_size, sample_rate, params));
#endif

#ifdef WIN32
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackPortAudioAdapter(buffer_size, sample_rate, params));
#endif

#ifdef __APPLE__
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackCoreAudioAdapter(buffer_size, sample_rate, params));
#endif

#if defined(__sun__) || defined(sun)
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackOSSAdapter(buffer_size, sample_rate, params));
#endif

adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackPlatformAdapter(buffer_size, sample_rate, params));
assert(adapter);

if (adapter->Open() == 0) {
@@ -82,6 +73,7 @@ extern "C"
}

} catch (...) {
jack_info("audioadapter allocation error");
return 1;
}
}


+ 1
- 1
common/JackConstants.h View File

@@ -24,7 +24,7 @@
#include "config.h"
#endif

#define VERSION "1.9.9"
#define VERSION "1.9.9.5"

#define BUFFER_SIZE_MAX 8192



+ 100
- 70
common/JackControlAPI.cpp View File

@@ -113,7 +113,6 @@ struct jackctl_driver
{
jack_driver_desc_t * desc_ptr;
JSList * parameters;
JSList * set_parameters;
JSList * infos;
};

@@ -121,7 +120,6 @@ struct jackctl_internal
{
jack_driver_desc_t * desc_ptr;
JSList * parameters;
JSList * set_parameters;
int refnum;
};

@@ -139,7 +137,6 @@ struct jackctl_parameter
union jackctl_parameter_value default_value;
struct jackctl_driver * driver_ptr;
char id;
jack_driver_param_t * driver_parameter_ptr;
jack_driver_param_constraint_desc_t * constraint_ptr;
};

@@ -187,7 +184,6 @@ jackctl_add_parameter(
*value_ptr = *default_value_ptr = value;

parameter_ptr->driver_ptr = NULL;
parameter_ptr->driver_parameter_ptr = NULL;
parameter_ptr->id = 0;
parameter_ptr->constraint_ptr = constraint_ptr;

@@ -213,14 +209,6 @@ jackctl_free_driver_parameters(
free(driver_ptr->parameters);
driver_ptr->parameters = next_node_ptr;
}

while (driver_ptr->set_parameters)
{
next_node_ptr = driver_ptr->set_parameters->next;
free(driver_ptr->set_parameters->data);
free(driver_ptr->set_parameters);
driver_ptr->set_parameters = next_node_ptr;
}
}

static
@@ -295,6 +283,87 @@ fail:
return false;
}

/* destroy jack_driver_param_desc_t list created by jackctl_create_param_list() */
static void
jackctl_destroy_param_list(
JSList * params)
{
JSList * next;

while (params)
{
next = params->next;
free(params->data);
free(params);
params = next;
}
}

/* for drivers and internals are configured through jack_driver_param_t JSList */
/* this function creates such list from a jackctl_parameter list */
static
bool
jackctl_create_param_list(
const JSList * paramlist,
JSList ** retparamlist)
{
jackctl_parameter * param_ptr;
jack_driver_param_t * retparam_ptr;

*retparamlist = NULL;
while (paramlist != NULL)
{
param_ptr = (jackctl_parameter *)paramlist->data;
if (param_ptr->is_set)
{
/* jack_info("setting driver parameter %p ...", parameter_ptr); */
retparam_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t));
if (retparam_ptr == NULL)
{
jack_error ("Allocation of jack_driver_param_t structure failed");
goto destroy;
}

retparam_ptr->character = param_ptr->id;

switch (param_ptr->type)
{
case JackParamInt:
retparam_ptr->value.i = param_ptr->value_ptr->i;
break;
case JackParamUInt:
retparam_ptr->value.ui = param_ptr->value_ptr->ui;
break;
case JackParamChar:
retparam_ptr->value.c = param_ptr->value_ptr->c;
break;
case JackParamString:
strcpy(retparam_ptr->value.str, param_ptr->value_ptr->str);
break;
case JackParamBool:
retparam_ptr->value.i = param_ptr->value_ptr->b;
break;
default:
jack_error("Unknown parameter type %i", (int)param_ptr->type);
assert(0);
goto free;
}

*retparamlist = jack_slist_append(*retparamlist, retparam_ptr);
}

paramlist = paramlist->next;
}

return true;

free:
free(retparam_ptr);
destroy:
jackctl_destroy_param_list(*retparamlist);
return false;
}

static int
jackctl_drivers_load(
struct jackctl_server * server_ptr)
@@ -321,7 +390,6 @@ jackctl_drivers_load(

driver_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data;
driver_ptr->parameters = NULL;
driver_ptr->set_parameters = NULL;
driver_ptr->infos = NULL;

if (!jackctl_add_driver_parameters(driver_ptr))
@@ -391,7 +459,6 @@ jackctl_internals_load(

internal_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data;
internal_ptr->parameters = NULL;
internal_ptr->set_parameters = NULL;
internal_ptr->refnum = -1;

if (!jackctl_add_driver_parameters((struct jackctl_driver *)internal_ptr))
@@ -934,6 +1001,7 @@ jackctl_server_open(
jackctl_driver *driver_ptr)
{
JackSelfConnectMode self_connect_mode;
JSList * paramlist = NULL;

try {

@@ -1011,7 +1079,9 @@ jackctl_server_open(
goto fail_unregister;
}

rc = server_ptr->engine->Open(driver_ptr->desc_ptr, driver_ptr->set_parameters);
if (!jackctl_create_param_list(driver_ptr->parameters, &paramlist)) goto fail_delete;
rc = server_ptr->engine->Open(driver_ptr->desc_ptr, paramlist);
jackctl_destroy_param_list(paramlist);
if (rc < 0)
{
jack_error("JackServer::Open failed with %d", rc);
@@ -1022,6 +1092,7 @@ jackctl_server_open(

} catch (std::exception e) {
jack_error("jackctl_server_open error...");
jackctl_destroy_param_list(paramlist);
}

fail_delete:
@@ -1110,7 +1181,7 @@ SERVER_EXPORT bool jackctl_parameter_has_enum_constraint(jackctl_parameter *para
SERVER_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter *parameter_ptr)
{
if (!parameter_ptr) {
return NULL;
return 0;
}

if (!jackctl_parameter_has_enum_constraint(parameter_ptr))
@@ -1242,57 +1313,6 @@ SERVER_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr,
return NULL;
}

bool new_driver_parameter;

/* for driver parameters, set the parameter by adding jack_driver_param_t in the set_parameters list */
if (parameter_ptr->driver_ptr != NULL)
{
/* jack_info("setting driver parameter %p ...", parameter_ptr); */
new_driver_parameter = parameter_ptr->driver_parameter_ptr == NULL;
if (new_driver_parameter)
{
/* jack_info("new driver parameter..."); */
parameter_ptr->driver_parameter_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t));
if (parameter_ptr->driver_parameter_ptr == NULL)
{
jack_error ("Allocation of jack_driver_param_t structure failed");
return false;
}

parameter_ptr->driver_parameter_ptr->character = parameter_ptr->id;
parameter_ptr->driver_ptr->set_parameters = jack_slist_append(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr);
}

switch (parameter_ptr->type)
{
case JackParamInt:
parameter_ptr->driver_parameter_ptr->value.i = value_ptr->i;
break;
case JackParamUInt:
parameter_ptr->driver_parameter_ptr->value.ui = value_ptr->ui;
break;
case JackParamChar:
parameter_ptr->driver_parameter_ptr->value.c = value_ptr->c;
break;
case JackParamString:
strcpy(parameter_ptr->driver_parameter_ptr->value.str, value_ptr->str);
break;
case JackParamBool:
parameter_ptr->driver_parameter_ptr->value.i = value_ptr->b;
break;
default:
jack_error("Unknown parameter type %i", (int)parameter_ptr->type);
assert(0);

if (new_driver_parameter)
{
parameter_ptr->driver_ptr->set_parameters = jack_slist_remove(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr);
}

return false;
}
}

parameter_ptr->is_set = true;
*parameter_ptr->value_ptr = *value_ptr;

@@ -1337,7 +1357,10 @@ SERVER_EXPORT bool jackctl_server_load_internal(

int status;
if (server_ptr->engine != NULL) {
server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status);
JSList * paramlist;
if (!jackctl_create_param_list(internal->parameters, &paramlist)) return false;
server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, paramlist, JackNullOption, &internal->refnum, -1, &status);
jackctl_destroy_param_list(paramlist);
return (internal->refnum > 0);
} else {
return false;
@@ -1368,7 +1391,10 @@ SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl
jack_error("Cannot add a slave in a running server");
return false;
} else {
JackDriverInfo* info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters);
JSList * paramlist;
if (!jackctl_create_param_list(driver_ptr->parameters, &paramlist)) return false;
JackDriverInfo* info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, paramlist);
jackctl_destroy_param_list(paramlist);
if (info) {
driver_ptr->infos = jack_slist_append(driver_ptr->infos, info);
return true;
@@ -1407,7 +1433,11 @@ SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jack
SERVER_EXPORT bool jackctl_server_switch_master(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
{
if (server_ptr && server_ptr->engine) {
return (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, driver_ptr->set_parameters) == 0);
JSList * paramlist;
if (!jackctl_create_param_list(driver_ptr->parameters, &paramlist)) return false;
bool ret = (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, paramlist) == 0);
jackctl_destroy_param_list(paramlist);
return ret;
} else {
return false;
}


+ 18
- 2
common/JackEngine.cpp View File

@@ -205,6 +205,22 @@ Client that finish *after* the callback date are considered late even if their o
correctly mixed in the time window: callbackUsecs <==> Read <==> Write.
*/

static const char* State2String(jack_client_state_t state)
{
switch (state) {
case NotTriggered:
return "NotTriggered";
case Triggered:
return "Triggered";
case Running:
return "Running";
case Finished:
return "Finished";
default:
return "";
}
}

void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions de fin
{
for (int i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) {
@@ -215,7 +231,7 @@ void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions
jack_time_t finished_date = timing->fFinishedAt;

if (status != NotTriggered && status != Finished) {
jack_error("JackEngine::XRun: client = %s was not run: state = %ld", client->GetClientControl()->fName, status);
jack_error("JackEngine::XRun: client = %s was not finished, state = %s", client->GetClientControl()->fName, State2String(status));
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients
}

@@ -352,8 +368,8 @@ void JackEngine::NotifyXRun(int refnum)

void JackEngine::NotifyGraphReorder()
{
NotifyClients(kGraphOrderCallback, false, "", 0, 0);
ComputeTotalLatencies();
NotifyClients(kGraphOrderCallback, false, "", 0, 0);
}

void JackEngine::NotifyBufferSize(jack_nframes_t buffer_size)


+ 0
- 3
common/JackInternalClient.cpp View File

@@ -27,10 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackServer.h"
#include "JackEngineControl.h"
#include "JackClientControl.h"

#include "JackInternalClientChannel.h"
#include "JackGenericClientChannel.h"

#include "JackTools.h"
#include <assert.h>



+ 2
- 2
common/JackLibAPI.cpp View File

@@ -166,7 +166,7 @@ static jack_client_t* jack_client_open_aux(const char* client_name, jack_options

LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
{
JackGlobals::CheckContext("jack_client_open");
JackGlobals::CheckContext("jack_client_open");

try {
assert(JackGlobals::fOpenMutex);
@@ -177,7 +177,7 @@ LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_opt
va_end(ap);
JackGlobals::fOpenMutex->Unlock();
return res;
} catch(std::bad_alloc& e) {
} catch (std::bad_alloc& e) {
jack_error("Memory allocation error...");
return NULL;
} catch (...) {


+ 5
- 5
common/JackLockedEngine.h View File

@@ -41,7 +41,7 @@ catch (...) {
*/

#define CATCH_EXCEPTION_RETURN \
} catch(std::bad_alloc& e) { \
} catch (std::bad_alloc& e) { \
jack_error("Memory allocation error..."); \
return -1; \
} catch (...) { \
@@ -50,10 +50,10 @@ catch (...) {
} \

#define CATCH_CLOSE_EXCEPTION_RETURN \
} catch(std::bad_alloc& e) { \
} catch (std::bad_alloc& e) { \
jack_error("Memory allocation error..."); \
return -1; \
} catch(JackTemporaryException& e) { \
} catch (JackTemporaryException& e) { \
jack_error("JackTemporaryException : now quits..."); \
JackTools::KillServer(); \
return 0; \
@@ -63,7 +63,7 @@ catch (...) {
}

#define CATCH_EXCEPTION \
} catch(std::bad_alloc& e) { \
} catch (std::bad_alloc& e) { \
jack_error("Memory allocation error..."); \
} catch (...) { \
jack_error("Unknown error..."); \
@@ -327,8 +327,8 @@ class SERVER_EXPORT JackLockedEngine

void NotifyQuit()
{
// No lock needed
TRY_CALL
JackLock lock(&fEngine);
return fEngine.NotifyQuit();
CATCH_EXCEPTION
}


+ 3
- 10
common/JackMidiDriver.cpp View File

@@ -136,9 +136,7 @@ int JackMidiDriver::SetBufferSize(jack_nframes_t buffer_size)
int JackMidiDriver::ProcessReadSync()
{
int res = 0;
jack_log("JackMidiDriver::ProcessReadSync");

// Read input buffers for the current cycle
if (Read() < 0) {
jack_error("JackMidiDriver::ProcessReadSync: read error");
@@ -156,9 +154,7 @@ int JackMidiDriver::ProcessReadSync()
int JackMidiDriver::ProcessWriteSync()
{
int res = 0;
jack_log("JackMidiDriver::ProcessWriteSync");

if (SuspendRefNum() < 0) {
jack_error("JackMidiDriver::ProcessWriteSync: SuspendRefNum error");
res = -1;
@@ -176,9 +172,7 @@ int JackMidiDriver::ProcessWriteSync()
int JackMidiDriver::ProcessReadAsync()
{
int res = 0;
jack_log("JackMidiDriver::ProcessReadAsync");

// Read input buffers for the current cycle
if (Read() < 0) {
jack_error("JackMidiDriver::ProcessReadAsync: read error");
@@ -201,7 +195,6 @@ int JackMidiDriver::ProcessReadAsync()

int JackMidiDriver::ProcessWriteAsync()
{
jack_log("JackMidiDriver::ProcessWriteAsync");
return 0;
}



+ 6
- 1
common/JackNetAPI.cpp View File

@@ -37,7 +37,7 @@ extern "C"
JackFloatEncoder = 0,
JackIntEncoder = 1,
JackCeltEncoder = 2,
JackMaxEncoder = 3
JackOpusEncoder = 3
};

typedef struct {
@@ -551,6 +551,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
return -1;
}
if ((fParams.fSampleEncoder == JackOpusEncoder) && (fParams.fKBps == 0)) {
jack_error("Opus encoder with 0 for kps...");
return -1;
}

// Check latency
if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
jack_error("Error : network latency is limited to %d", NETWORK_MAX_LATENCY);


+ 15
- 2
common/JackNetAdapter.cpp View File

@@ -101,6 +101,14 @@ namespace Jack
fParams.fKBps = param->value.i;
}
break;
#endif
#if HAVE_OPUS
case 'O':
if (param->value.i > 0) {
fParams.fSampleEncoder = JackOpusEncoder;
fParams.fKBps = param->value.i;
}
break;
#endif
case 'l' :
fParams.fNetworkLatency = param->value.i;
@@ -404,7 +412,7 @@ extern "C"
desc = jack_driver_descriptor_construct("netadapter", JackDriverNone, "netjack net <==> audio backend adapter", &filler);

strcpy(value.str, DEFAULT_MULTICAST_IP);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address, or explicit IP of the master", NULL);

value.i = DEFAULT_PORT;
jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);
@@ -421,6 +429,11 @@ extern "C"
jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamInt, &value, NULL, "Set CELT encoding and number of kBits per channel", NULL);
#endif

#if HAVE_OPUS
value.i = -1;
jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'O', JackDriverParamInt, &value, NULL, "Set Opus encoding and number of kBits per channel", NULL);
#endif

strcpy(value.str, "'hostname'");
jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL);

@@ -463,7 +476,7 @@ extern "C"
}

} catch (...) {
jack_info("NetAdapter allocation error");
jack_info("netadapter allocation error");
return 1;
}
}


+ 16
- 3
common/JackNetDriver.cpp View File

@@ -29,7 +29,7 @@ namespace Jack
{
JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports,
char* net_name, uint transport_sync, int network_latency, int celt_encoding)
char* net_name, uint transport_sync, int network_latency, int celt_encoding, int opus_encoding)
: JackWaiterDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port)
{
jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port);
@@ -45,6 +45,9 @@ namespace Jack
if (celt_encoding > 0) {
fParams.fSampleEncoder = JackCeltEncoder;
fParams.fKBps = celt_encoding;
} else if (opus_encoding > 0) {
fParams.fSampleEncoder = JackOpusEncoder;
fParams.fKBps = opus_encoding;
} else {
fParams.fSampleEncoder = JackFloatEncoder;
//fParams.fSampleEncoder = JackIntEncoder;
@@ -600,7 +603,7 @@ namespace Jack
desc = jack_driver_descriptor_construct("net", JackDriverMaster, "netjack slave backend component", &filler);

strcpy(value.str, DEFAULT_MULTICAST_IP);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address, or explicit IP of the master", NULL);

value.i = DEFAULT_PORT;
jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);
@@ -619,6 +622,10 @@ namespace Jack
#if HAVE_CELT
value.i = -1;
jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamInt, &value, NULL, "Set CELT encoding and number of kBits per channel", NULL);
#endif
#if HAVE_OPUS
value.i = -1;
jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'O', JackDriverParamInt, &value, NULL, "Set Opus encoding and number of kBits per channel", NULL);
#endif
strcpy(value.str, "'hostname'");
jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL);
@@ -650,6 +657,7 @@ Deactivated for now..
int midi_input_ports = 0;
int midi_output_ports = 0;
int celt_encoding = -1;
int opus_encoding = -1;
bool monitor = false;
int network_latency = 5;
const JSList* node;
@@ -699,6 +707,11 @@ Deactivated for now..
celt_encoding = param->value.i;
break;
#endif
#if HAVE_OPUS
case 'O':
opus_encoding = param->value.i;
break;
#endif
case 'n' :
strncpy(net_name, param->value.str, JACK_CLIENT_NAME_SIZE);
break;
@@ -724,7 +737,7 @@ Deactivated for now..
new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu,
midi_input_ports, midi_output_ports,
net_name, transport_sync,
network_latency, celt_encoding));
network_latency, celt_encoding, opus_encoding));
if (driver->Open(period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, monitor, "from_master_", "to_master_", 0, 0) == 0) {
return driver;
} else {


+ 1
- 1
common/JackNetDriver.h View File

@@ -69,7 +69,7 @@ namespace Jack

JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports,
char* net_name, uint transport_sync, int network_latency, int celt_encoding);
char* net_name, uint transport_sync, int network_latency, int celt_encoding, int opus_encoding);
virtual ~JackNetDriver();

int Close();


+ 4
- 0
common/JackNetInterface.cpp View File

@@ -243,6 +243,10 @@ namespace Jack
case JackCeltEncoder:
return new NetCeltAudioBuffer(&fParams, nports, buffer, fParams.fKBps);
#endif
#if HAVE_OPUS
case JackOpusEncoder:
return new NetOpusAudioBuffer(&fParams, nports, buffer, fParams.fKBps);
#endif
}
return NULL;
}


+ 1
- 1
common/JackNetManager.cpp View File

@@ -823,7 +823,7 @@ extern "C"
desc = jack_driver_descriptor_construct("netmanager", JackDriverNone, "netjack multi-cast master component", &filler);

strcpy(value.str, DEFAULT_MULTICAST_IP);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address", NULL);

value.i = DEFAULT_PORT;
jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);


+ 165
- 0
common/JackNetOneDriver.cpp View File

@@ -39,6 +39,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <celt/celt.h>
#endif

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#define MIN(x,y) ((x)<(y) ? (x) : (y))

using namespace std;
@@ -146,6 +151,12 @@ int JackNetOneDriver::AllocPorts()
#endif
celt_mode_info(celt_mode, CELT_GET_LOOKAHEAD, &lookahead);
netj.codec_latency = 2 * lookahead;
#endif
} else if (netj.bitdepth == OPUS_MODE) {
#if HAVE_OPUS
OpusCustomMode *opus_mode = opus_custom_mode_create(netj.sample_rate, netj.period_size, NULL); // XXX free me in the end
OpusCustomDecoder *decoder = opus_custom_decoder_create( opus_mode, 1, NULL );
netj.capture_srcs = jack_slist_append(netj.capture_srcs, decoder);
#endif
} else {
#if HAVE_SAMPLERATE
@@ -191,6 +202,21 @@ int JackNetOneDriver::AllocPorts()
CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL);
netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode));
#endif
#endif
} else if (netj.bitdepth == OPUS_MODE) {
#if HAVE_OPUS
const int kbps = netj.resample_factor;
jack_error("NEW ONE OPUS ENCODER 128 <> %d!!", kbps);
int err;
OpusCustomMode *opus_mode = opus_custom_mode_create( netj.sample_rate, netj.period_size, &err ); // XXX free me in the end
if (err != OPUS_OK) { jack_error("opus mode failed"); }
OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err );
if (err != OPUS_OK) { jack_error("opus mode failed"); }
opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
netj.playback_srcs = jack_slist_append(netj.playback_srcs, oe);
#endif
} else {
#if HAVE_SAMPLERATE
@@ -450,6 +476,28 @@ JackNetOneDriver::FreePorts ()
celt_decoder_destroy(dec);
}
netj.capture_srcs = NULL;
#endif
} else if (netj.bitdepth == OPUS_MODE) {
#if HAVE_OPUS
node = netj.playback_srcs;
while (node != NULL) {
JSList *this_node = node;
OpusCustomEncoder *enc = (OpusCustomEncoder *) node->data;
node = jack_slist_remove_link(node, this_node);
jack_slist_free_1(this_node);
opus_custom_encoder_destroy(enc);
}
netj.playback_srcs = NULL;

node = netj.capture_srcs;
while (node != NULL) {
JSList *this_node = node;
OpusCustomDecoder *dec = (OpusCustomDecoder *) node->data;
node = jack_slist_remove_link(node, this_node);
jack_slist_free_1(this_node);
opus_custom_decoder_destroy(dec);
}
netj.capture_srcs = NULL;
#endif
} else {
#if HAVE_SAMPLERATE
@@ -724,6 +772,98 @@ JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSL
}

#endif

#if HAVE_OPUS
#define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
// render functions for Opus.
void
JackNetOneDriver::render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
{
int chn = 0;
JSList *node = capture_ports;
JSList *src_node = capture_srcs;

unsigned char *packet_bufX = (unsigned char *)packet_payload;

while (node != NULL) {
jack_port_id_t port_index = (jack_port_id_t) (intptr_t)node->data;
JackPort *port = fGraphManager->GetPort(port_index);

jack_default_audio_sample_t* buf =
(jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);

const char *portname = port->GetType();

if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
// audio port, decode opus data.
OpusCustomDecoder *decoder = (OpusCustomDecoder*) src_node->data;
if( !packet_payload )
memset(buf, 0, nframes * sizeof(float));
else {
unsigned short len;
memcpy(&len, packet_bufX, CDO);
len = ntohs(len);
opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes );
}

src_node = jack_slist_next (src_node);
} else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
// midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2;
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
if( packet_payload )
decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
}
packet_bufX = (packet_bufX + net_period_down);
node = jack_slist_next (node);
chn++;
}
}

void
JackNetOneDriver::render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
{
int chn = 0;
JSList *node = playback_ports;
JSList *src_node = playback_srcs;

unsigned char *packet_bufX = (unsigned char *)packet_payload;

while (node != NULL) {
jack_port_id_t port_index = (jack_port_id_t) (intptr_t) node->data;
JackPort *port = fGraphManager->GetPort(port_index);

jack_default_audio_sample_t* buf =
(jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);

const char *portname = port->GetType();

if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
// audio port, encode opus data.

int encoded_bytes;
jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes);
memcpy(floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t));
OpusCustomEncoder *encoder = (OpusCustomEncoder*) src_node->data;
encoded_bytes = opus_custom_encode_float( encoder, floatbuf, nframes, packet_bufX + CDO, net_period_up - CDO );
unsigned short len = htons(encoded_bytes);
memcpy(packet_bufX, &len, CDO);
src_node = jack_slist_next( src_node );
} else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
// encode midi events from port to packet
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_up / 2;
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
}
packet_bufX = (packet_bufX + net_period_up);
node = jack_slist_next (node);
chn++;
}
}
#endif

/* Wrapper functions with bitdepth argument... */
void
JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
@@ -732,6 +872,11 @@ JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_paylo
if (bitdepth == CELT_MODE)
render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
else
#endif
#if HAVE_OPUS
if (bitdepth == OPUS_MODE)
render_payload_to_jack_ports_opus (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
else
#endif
render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
}
@@ -743,6 +888,11 @@ JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_p
if (bitdepth == CELT_MODE)
render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
else
#endif
#if HAVE_OPUS
if (bitdepth == OPUS_MODE)
render_jack_ports_to_payload_opus (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
else
#endif
render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);
}
@@ -791,6 +941,10 @@ extern "C"
#if HAVE_CELT
value.ui = 0U;
jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamUInt, &value, NULL, "Set CELT encoding and number of kbits per channel", NULL);
#endif
#if HAVE_OPUS
value.ui = 0U;
jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'P', JackDriverParamUInt, &value, NULL, "Set Opus encoding and number of kbits per channel", NULL);
#endif
value.ui = 0U;
jack_driver_descriptor_add_parameter(desc, &filler, "bit-depth", 'b', JackDriverParamUInt, &value, NULL, "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)", NULL);
@@ -904,6 +1058,17 @@ extern "C"
#endif
break;

case 'P':
#if HAVE_OPUS
bitdepth = OPUS_MODE;
resample_factor = param->value.ui;
jack_error("OPUS: %d\n", resample_factor);
#else
jack_error("not built with Opus support");
return NULL;
#endif
break;

case 't':
handle_transport_sync = param->value.ui;
break;


+ 6
- 0
common/JackNetOneDriver.h View File

@@ -45,6 +45,12 @@ class JackNetOneDriver : public JackWaiterDriver
render_payload_to_jack_ports_celt(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes);
void
render_jack_ports_to_payload_celt(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up);
#endif
#if HAVE_OPUS
void
render_payload_to_jack_ports_opus(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes);
void
render_jack_ports_to_payload_opus(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up);
#endif
void
render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats);


+ 234
- 0
common/JackNetTool.cpp View File

@@ -709,6 +709,227 @@ namespace Jack

#endif

#if HAVE_OPUS
#define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)

NetOpusAudioBuffer::NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
:NetAudioBuffer(params, nports, net_buffer)
{
fOpusMode = new OpusCustomMode *[fNPorts];
fOpusEncoder = new OpusCustomEncoder *[fNPorts];
fOpusDecoder = new OpusCustomDecoder *[fNPorts];
fCompressedSizesByte = new unsigned short [fNPorts];

memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*));
memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*));
memset(fOpusDecoder, 0, fNPorts * sizeof(OpusCustomDecoder*));
memset(fCompressedSizesByte, 0, fNPorts * sizeof(int));

int error = OPUS_OK;

for (int i = 0; i < fNPorts; i++) {
/* Allocate en/decoders */
fOpusMode[i] = opus_custom_mode_create(
params->fSampleRate, params->fPeriodSize, &error);
if (error != OPUS_OK) {
goto error;
}

fOpusEncoder[i] = opus_custom_encoder_create(fOpusMode[i], 1,&error);
if (error != OPUS_OK) {
goto error;
}

fOpusDecoder[i] = opus_custom_decoder_create(fOpusMode[i], 1, &error);
if (error != OPUS_OK) {
goto error;
}

opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
}

{
fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
fPeriodSize = params->fPeriodSize;
jack_log("NetOpusAudioBuffer fCompressedMaxSizeByte %d", fCompressedMaxSizeByte);

fCompressedBuffer = new unsigned char* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++) {
fCompressedBuffer[port_index] = new unsigned char[fCompressedMaxSizeByte];
memset(fCompressedBuffer[port_index], 0, fCompressedMaxSizeByte * sizeof(char));
}

int res1 = (fNPorts * fCompressedMaxSizeByte + CDO) % PACKET_AVAILABLE_SIZE(params);
int res2 = (fNPorts * fCompressedMaxSizeByte + CDO) / PACKET_AVAILABLE_SIZE(params);

fNumPackets = (res1) ? (res2 + 1) : res2;

jack_log("NetOpusAudioBuffer res1 = %d res2 = %d", res1, res2);

fSubPeriodBytesSize = (fCompressedMaxSizeByte + CDO) / fNumPackets;
fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedMaxSizeByte + CDO) % fNumPackets;

if (fNumPackets == 1) {
fSubPeriodBytesSize = fLastSubPeriodBytesSize;
}

jack_log("NetOpusAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);

fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleBytesSize = params->fMtu * fNumPackets;

fLastSubCycle = -1;
return;
}

error:

FreeOpus();
throw std::bad_alloc();
}

NetOpusAudioBuffer::~NetOpusAudioBuffer()
{
FreeOpus();

for (int port_index = 0; port_index < fNPorts; port_index++) {
delete [] fCompressedBuffer[port_index];
}

delete [] fCompressedBuffer;
delete [] fCompressedSizesByte;
}

void NetOpusAudioBuffer::FreeOpus()
{
for (int i = 0; i < fNPorts; i++) {
if (fOpusEncoder[i]) {
opus_custom_encoder_destroy(fOpusEncoder[i]);
fOpusEncoder[i]=0;
}
if (fOpusDecoder[i]) {
opus_custom_decoder_destroy(fOpusDecoder[i]);
fOpusDecoder[i]=0;
}
if (fOpusMode[i]) {
opus_custom_mode_destroy(fOpusMode[i]);
fOpusMode[i]=0;
}
}

delete [] fOpusEncoder;
delete [] fOpusDecoder;
delete [] fOpusMode;
}

size_t NetOpusAudioBuffer::GetCycleSize()
{
return fCycleBytesSize;
}

float NetOpusAudioBuffer::GetCycleDuration()
{
return fCycleDuration;
}

int NetOpusAudioBuffer::GetNumPackets(int active_ports)
{
return fNumPackets;
}

int NetOpusAudioBuffer::RenderFromJackPorts()
{
float buffer[BUFFER_SIZE_MAX];

for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
} else {
memset(buffer, 0, fPeriodSize * sizeof(sample_t));
}
int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedMaxSizeByte);
if (res <0 || res >= 65535) {
fCompressedSizesByte[port_index] = 0;
} else {
fCompressedSizesByte[port_index] = res;
}
}

// All ports active
return fNPorts;
}

void NetOpusAudioBuffer::RenderToJackPorts()
{
for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
int res = opus_custom_decode_float(fOpusDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizesByte[port_index], fPortBuffer[port_index], fPeriodSize);
if (res < 0 || res != fPeriodSize) {
jack_error("opus_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res);
}
}
}

NextCycle();
}

//network<->buffer
int NetOpusAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{
// Cleanup all JACK ports at the beginning of the cycle
if (sub_cycle == 0) {
Cleanup();
}

if (port_num > 0) {
if (sub_cycle == 0) {
for (int port_index = 0; port_index < fNPorts; port_index++) {
size_t len = *((size_t*)(fNetBuffer + port_index * fSubPeriodBytesSize));
fCompressedSizesByte[port_index] = ntohs(len);
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + CDO + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize - CDO);
}
} else if (sub_cycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
}
} else {
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
}
}

return CheckPacket(cycle, sub_cycle);
}

int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{
if (sub_cycle == 0) {
for (int port_index = 0; port_index < fNPorts; port_index++) {
unsigned short len = htons(fCompressedSizesByte[port_index]);
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, &len, CDO);
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize + CDO, fCompressedBuffer[port_index], fSubPeriodBytesSize - CDO);
}
return fNPorts * fSubPeriodBytesSize;
} else if (sub_cycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fLastSubPeriodBytesSize);
}
return fNPorts * fLastSubPeriodBytesSize;
} else {
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fSubPeriodBytesSize);
}
return fNPorts * fSubPeriodBytesSize;
}
}

#endif


NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
: NetAudioBuffer(params, nports, net_buffer)
{
@@ -840,6 +1061,7 @@ namespace Jack
SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params)
{
memcpy(dst_params, src_params, sizeof(session_params_t));
dst_params->fProtocolVersion = htonl(src_params->fProtocolVersion);
dst_params->fPacketID = htonl(src_params->fPacketID);
dst_params->fMtu = htonl(src_params->fMtu);
dst_params->fID = htonl(src_params->fID);
@@ -859,6 +1081,7 @@ namespace Jack
SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params)
{
memcpy(dst_params, src_params, sizeof(session_params_t));
dst_params->fProtocolVersion = ntohl(src_params->fProtocolVersion);
dst_params->fPacketID = ntohl(src_params->fPacketID);
dst_params->fMtu = ntohl(src_params->fMtu);
dst_params->fID = ntohl(src_params->fID);
@@ -889,6 +1112,9 @@ namespace Jack
case JackCeltEncoder:
strcpy(encoder, "CELT");
break;
case JackOpusEncoder:
strcpy(encoder, "OPUS");
break;
}

jack_info("**************** Network parameters ****************");
@@ -915,6 +1141,10 @@ namespace Jack
jack_info("SampleEncoder : %s", "CELT");
jack_info("kBits : %d", params->fKBps);
break;
case (JackOpusEncoder):
jack_info("SampleEncoder : %s", "OPUS");
jack_info("kBits : %d", params->fKBps);
break;
};
jack_info("Slave mode : %s", (params->fSlaveSyncMode) ? "sync" : "async");
jack_info("****************************************************");
@@ -967,6 +1197,8 @@ namespace Jack
SERVER_EXPORT void PacketHeaderHToN(packet_header_t* src_header, packet_header_t* dst_header)
{
memcpy(dst_header, src_header, sizeof(packet_header_t));
dst_header->fDataType = htonl(src_header->fDataType);
dst_header->fDataStream = htonl(src_header->fDataStream);
dst_header->fID = htonl(src_header->fID);
dst_header->fNumPacket = htonl(src_header->fNumPacket);
dst_header->fPacketSize = htonl(src_header->fPacketSize);
@@ -979,6 +1211,8 @@ namespace Jack
SERVER_EXPORT void PacketHeaderNToH(packet_header_t* src_header, packet_header_t* dst_header)
{
memcpy(dst_header, src_header, sizeof(packet_header_t));
dst_header->fDataType = ntohl(src_header->fDataType);
dst_header->fDataStream = ntohl(src_header->fDataStream);
dst_header->fID = ntohl(src_header->fID);
dst_header->fNumPacket = ntohl(src_header->fNumPacket);
dst_header->fPacketSize = ntohl(src_header->fPacketSize);


+ 60
- 11
common/JackNetTool.h View File

@@ -38,8 +38,8 @@ using namespace std;
#endif
#endif

#define MASTER_PROTOCOL 5
#define SLAVE_PROTOCOL 5
#define MASTER_PROTOCOL 6
#define SLAVE_PROTOCOL 6

#define NET_PACKET_ERROR -2

@@ -62,6 +62,7 @@ namespace Jack
JackFloatEncoder = 0,
JackIntEncoder = 1,
JackCeltEncoder = 2,
JackOpusEncoder = 3,
};

//session params ******************************************************************************
@@ -83,11 +84,12 @@ namespace Jack
are kept in LITTLE_ENDIAN format (to avoid 2 conversions in the more common LITTLE_ENDIAN <==> LITTLE_ENDIAN connection case).
*/

PRE_PACKED_STRUCTURE
struct _session_params
{
char fPacketType[7]; //packet type ('param')
char fProtocolVersion; //version
uint32_t fPacketID; //indicates the packet type
char fPacketType[8]; //packet type ('param')
uint32_t fProtocolVersion; //version
int32_t fPacketID; //indicates the packet type
char fName[JACK_CLIENT_NAME_SIZE]; //slave's name
char fMasterNetName[256]; //master hostname (network)
char fSlaveNetName[256]; //slave hostname (network)
@@ -104,7 +106,7 @@ namespace Jack
uint32_t fKBps; //KB per second for CELT encoder
uint32_t fSlaveSyncMode; //is the slave in sync mode ?
uint32_t fNetworkLatency; //network latency
};
} POST_PACKED_STRUCTURE;

//net status **********************************************************************************

@@ -165,11 +167,12 @@ namespace Jack

*/

PRE_PACKED_STRUCTURE
struct _packet_header
{
char fPacketType[7]; //packet type ('headr')
char fDataType; //a for audio, m for midi and s for sync
char fDataStream; //s for send, r for return
char fPacketType[8]; //packet type ('headr')
uint32_t fDataType; //a for audio, m for midi and s for sync
uint32_t fDataStream; //s for send, r for return
uint32_t fID; //unique ID of the slave
uint32_t fNumPacket; //number of data packets of the cycle
uint32_t fPacketSize; //packet size in bytes
@@ -177,7 +180,7 @@ namespace Jack
uint32_t fCycle; //process cycle counter
uint32_t fSubCycle; //midi/audio subcycle counter
uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n')
};
} POST_PACKED_STRUCTURE;

//net timebase master

@@ -202,13 +205,14 @@ namespace Jack
\Brief This structure contains transport data to be sent over the network
*/

PRE_PACKED_STRUCTURE
struct _net_transport_data
{
uint32_t fNewState; //is it a state change
uint32_t fTimebaseMaster; //is there a new timebase master
int32_t fState; //current cycle state
jack_position_t fPosition; //current cycle position
};
} POST_PACKED_STRUCTURE;

//midi data ***********************************************************************************

@@ -400,6 +404,51 @@ namespace Jack
int RenderToNetwork(int sub_cycle, uint32_t port_num);
};

#endif

#if HAVE_OPUS

#include <opus/opus.h>
#include <opus/opus_custom.h>

class SERVER_EXPORT NetOpusAudioBuffer : public NetAudioBuffer
{
private:

OpusCustomMode** fOpusMode;
OpusCustomEncoder** fOpusEncoder;
OpusCustomDecoder** fOpusDecoder;

unsigned short *fCompressedSizesByte;
int fCompressedMaxSizeByte;
int fNumPackets;

size_t fLastSubPeriodBytesSize;

unsigned char** fCompressedBuffer;
void FreeOpus();

public:

NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
virtual ~NetOpusAudioBuffer();

// needed size in bytes for an entire cycle
size_t GetCycleSize();

// cycle duration in sec
float GetCycleDuration();
int GetNumPackets(int active_ports);

//jack<->buffer
int RenderFromJackPorts();
void RenderToJackPorts();

//network<->buffer
int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t port_num);
};

#endif

class SERVER_EXPORT NetIntAudioBuffer : public NetAudioBuffer


+ 2
- 2
common/JackPort.h View File

@@ -58,7 +58,7 @@ class SERVER_EXPORT JackPort

bool fInUse;
jack_port_id_t fTied; // Locally tied source port
jack_default_audio_sample_t fBuffer[BUFFER_SIZE_MAX + 4];
jack_default_audio_sample_t fBuffer[BUFFER_SIZE_MAX + 8];

bool IsUsed() const
{
@@ -108,7 +108,7 @@ class SERVER_EXPORT JackPort
// Since we are in shared memory, the resulting pointer cannot be cached, so align it here...
jack_default_audio_sample_t* GetBuffer()
{
return (jack_default_audio_sample_t*)((uintptr_t)fBuffer & ~15L) + 4;
return (jack_default_audio_sample_t*)((uintptr_t)fBuffer & ~31L) + 8;
}

int GetRefNum() const;


+ 2
- 2
common/JackRequestDecoder.cpp View File

@@ -46,7 +46,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
{
JackRequest::RequestType type = (JackRequest::RequestType)type_aux;

// Read data
// Read data
switch (type) {

case JackRequest::kClientCheck: {
@@ -82,7 +82,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
CheckRead(req, socket);
res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
CheckWriteRefNum("JackRequest::ClientClose", socket);
fHandler->ClientRemove(socket, req.fRefNum);
fHandler->ClientRemove(socket, req.fRefNum);
// Will cause the wrapping thread to stop
return -1;
}


+ 1
- 1
common/JackServer.cpp View File

@@ -134,7 +134,6 @@ fail_close1:
int JackServer::Close()
{
jack_log("JackServer::Close");
fEngine->NotifyQuit();
fChannel.Close();
fAudioDriver->Detach();
fAudioDriver->Close();
@@ -190,6 +189,7 @@ int JackServer::Start()
int JackServer::Stop()
{
jack_log("JackServer::Stop");
fEngine->NotifyQuit();
fChannel.Stop();
fEngine->ShutDown();


+ 1
- 1
common/JackServerAPI.cpp View File

@@ -162,7 +162,7 @@ SERVER_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_
va_end(ap);
JackGlobals::fOpenMutex->Unlock();
return res;
} catch(std::bad_alloc& e) {
} catch (std::bad_alloc& e) {
jack_error("Memory allocation error...");
return NULL;
} catch (...) {


+ 0
- 10
common/JackServerGlobals.cpp View File

@@ -101,9 +101,7 @@ bool JackServerGlobals::Init()
int client_timeout = 0; /* msecs; if zero, use period size. */
int realtime_priority = 10;
int verbose_aux = 0;
int do_mlock = 1;
unsigned int port_max = 128;
int do_unlock = 0;
int temporary = 0;

int opt = 0;
@@ -234,14 +232,6 @@ bool JackServerGlobals::Init()
port_max = (unsigned int)atol(optarg);
break;

case 'm':
do_mlock = 0;
break;

case 'u':
do_unlock = 1;
break;

case 'v':
verbose_aux = 1;
break;


+ 0
- 10
common/Jackdmp.cpp View File

@@ -224,8 +224,6 @@ int main(int argc, char** argv)
char* master_driver_name = NULL;
char** master_driver_args = NULL;
int master_driver_nargs = 1;
int do_mlock = 1;
int do_unlock = 0;
int loopback = 0;
bool show_version = false;
jackctl_sigmask_t * sigmask;
@@ -324,14 +322,6 @@ int main(int argc, char** argv)
}
break;

case 'm':
do_mlock = 0;
break;

case 'u':
do_unlock = 1;
break;

case 'v':
param = jackctl_get_parameter(server_parameters, "verbose");
if (param != NULL) {


+ 1
- 1
common/jack/intclient.h View File

@@ -40,7 +40,7 @@ extern "C"
*
* @return NULL if unsuccessful, otherwise pointer to the internal
* client name obtained from the heap via malloc(). The caller should
* free() this storage when no longer needed.
* jack_free() this storage when no longer needed.
*/
char *jack_get_internal_client_name (jack_client_t *client,
jack_intclient_t intclient);


+ 4
- 4
common/jack/jack.h View File

@@ -798,7 +798,7 @@ int jack_port_connected_to (const jack_port_t *port,
* @return a null-terminated array of full port names to which the @a
* port is connected. If none, returns NULL.
*
* The caller is responsible for calling jack_free(3) on any non-NULL
* The caller is responsible for calling jack_free() on any non-NULL
* returned value.
*
* @param port locally owned jack_port_t pointer.
@@ -811,7 +811,7 @@ const char ** jack_port_get_connections (const jack_port_t *port) JACK_OPTIONAL_
* @return a null-terminated array of full port names to which the @a
* port is connected. If none, returns NULL.
*
* The caller is responsible for calling jack_free(3) on any non-NULL
* The caller is responsible for calling jack_free() on any non-NULL
* returned value.
*
* This differs from jack_port_get_connections() in two important
@@ -1220,7 +1220,7 @@ int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTION
* If zero, no selection based on flags will be carried out.
*
* @return a NULL-terminated array of ports that match the specified
* arguments. The caller is responsible for calling jack_free(3) any
* arguments. The caller is responsible for calling jack_free() any
* non-NULL returned value.
*
* @see jack_port_name_size(), jack_port_type_size()
@@ -1400,7 +1400,7 @@ void jack_set_info_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXPO

/**
* The free function to be used on memory returned by jack_port_get_connections,
* jack_port_get_all_connections and jack_get_ports functions.
* jack_port_get_all_connections, jack_get_ports and jack_get_internal_client_name functions.
* This is MANDATORY on Windows when otherwise all nasty runtime version related crashes can occur.
* Developers are strongly encouraged to use this function instead of the standard "free" function in new code.
*


+ 1
- 0
common/jack/net.h View File

@@ -40,6 +40,7 @@ enum JackNetEncoder {
JackFloatEncoder = 0, // samples are transmitted as float
JackIntEncoder = 1, // samples are transmitted as 16 bits integer
JackCeltEncoder = 2, // samples are transmitted using CELT codec (http://www.celt-codec.org/)
JackOpusEncoder = 3, // samples are transmitted using OPUS codec (http://www.opus-codec.org/)
};

typedef struct {


+ 45
- 1
common/netjack.c View File

@@ -368,6 +368,11 @@ void netjack_attach( netjack_driver_state_t *netj )
netj->codec_latency = 2 * lookahead;
#endif
}
if( netj->bitdepth == OPUS_MODE ) {
#if HAVE_OPUS
netj->opus_mode = opus_custom_mode_create(netj->sample_rate, netj->period_size, NULL);
#endif
}

if (netj->handle_transport_sync)
jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL);
@@ -397,6 +402,11 @@ void netjack_attach( netjack_driver_state_t *netj )
#else
netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) );
#endif
#endif
} else if( netj->bitdepth == OPUS_MODE ) {
#if HAVE_OPUS
OpusCustomDecoder *decoder = opus_custom_decoder_create( netj->opus_mode, 1, NULL );
netj->capture_srcs = jack_slist_append(netj->capture_srcs, decoder );
#endif
} else {
#if HAVE_SAMPLERATE
@@ -448,6 +458,19 @@ void netjack_attach( netjack_driver_state_t *netj )
CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) );
#endif
#endif
} else if( netj->bitdepth == OPUS_MODE ) {
#if HAVE_OPUS
const int kbps = netj->resample_factor;
jack_log( "OPUS %dkbps\n", kbps);

OpusCustomMode *opus_mode = opus_custom_mode_create( netj->sample_rate, netj->period_size, NULL ); // XXX free me in the end
OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, NULL );
opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
netj->playback_srcs = jack_slist_append(netj->playback_srcs, oe );
#endif
} else {
#if HAVE_SAMPLERATE
@@ -492,6 +515,12 @@ void netjack_detach( netjack_driver_state_t *netj )
CELTDecoder * decoder = node->data;
celt_decoder_destroy(decoder);
} else
#endif
#if HAVE_OPUS
if ( netj->bitdepth == OPUS_MODE ) {
OpusCustomDecoder * decoder = node->data;
opus_custom_decoder_destroy(decoder);
} else
#endif
{
#if HAVE_SAMPLERATE
@@ -516,6 +545,12 @@ void netjack_detach( netjack_driver_state_t *netj )
CELTEncoder * encoder = node->data;
celt_encoder_destroy(encoder);
} else
#endif
#if HAVE_OPUS
if ( netj->bitdepth == OPUS_MODE ) {
OpusCustomEncoder * encoder = node->data;
opus_custom_encoder_destroy(encoder);
} else
#endif
{
#if HAVE_SAMPLERATE
@@ -531,6 +566,10 @@ void netjack_detach( netjack_driver_state_t *netj )
if( netj->bitdepth == CELT_MODE )
celt_mode_destroy(netj->celt_mode);
#endif
#if HAVE_OPUS
if( netj->bitdepth == OPUS_MODE )
opus_custom_mode_destroy(netj->opus_mode);
#endif
}


@@ -588,7 +627,7 @@ netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
netj->client = client;


if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE)) {
if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE) && (bitdepth != OPUS_MODE)) {
jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth);
return NULL;
}
@@ -755,6 +794,11 @@ netjack_startup( netjack_driver_state_t *netj )

netj->net_period_down = netj->resample_factor;
netj->net_period_up = netj->resample_factor_up;
} else if( netj->bitdepth == OPUS_MODE ) {
// Opus mode.
// TODO: this is a hack. But i dont want to change the packet header, either
netj->net_period_down = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
netj->net_period_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
} else {
netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor;
netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up;


+ 8
- 0
common/netjack.h View File

@@ -32,6 +32,11 @@
#include <celt/celt.h>
#endif

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#ifdef __cplusplus
extern "C"
{
@@ -111,6 +116,9 @@ extern "C"
struct _packet_cache * packcache;
#if HAVE_CELT
CELTMode *celt_mode;
#endif
#if HAVE_OPUS
OpusCustomMode* opus_mode;
#endif
};



+ 100
- 0
common/netjack_packet.c View File

@@ -72,6 +72,11 @@
#include <celt/celt.h>
#endif

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#include "netjack_packet.h"
#include "JackError.h"

@@ -129,6 +134,8 @@ int get_sample_size (int bitdepth)
//JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N?
if( bitdepth == CELT_MODE )
return sizeof( unsigned char );
if( bitdepth == OPUS_MODE )
return sizeof( unsigned char );
return sizeof (int32_t);
}

@@ -1347,6 +1354,91 @@ render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs
}

#endif

#if HAVE_OPUS
#define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
// render functions for Opus.
void
render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
{
int chn = 0;
JSList *node = capture_ports;
JSList *src_node = capture_srcs;

unsigned char *packet_bufX = (unsigned char *)packet_payload;

while (node != NULL) {
jack_port_t *port = (jack_port_t *) node->data;
jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);

const char *porttype = jack_port_type (port);

if (jack_port_is_audio (porttype)) {
// audio port, decode opus data.
OpusCustomDecoder *decoder = (OpusCustomDecoder*) src_node->data;
if( !packet_payload )
memset(buf, 0, nframes * sizeof(float));
else {
unsigned short len;
memcpy(&len, packet_bufX, CDO);
len = ntohs(len);
opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes );
}

src_node = jack_slist_next (src_node);
} else if (jack_port_is_midi (porttype)) {
// midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2;
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
if( packet_payload )
decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
}
packet_bufX = (packet_bufX + net_period_down);
node = jack_slist_next (node);
chn++;
}
}

void
render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
{
int chn = 0;
JSList *node = playback_ports;
JSList *src_node = playback_srcs;

unsigned char *packet_bufX = (unsigned char *)packet_payload;

while (node != NULL) {
jack_port_t *port = (jack_port_t *) node->data;
jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
const char *porttype = jack_port_type (port);

if (jack_port_is_audio (porttype)) {
// audio port, encode opus data.

int encoded_bytes;
float *floatbuf = alloca (sizeof(float) * nframes );
memcpy( floatbuf, buf, nframes * sizeof(float) );
OpusCustomEncoder *encoder = (OpusCustomEncoder*) src_node->data;
encoded_bytes = opus_custom_encode_float( encoder, floatbuf, nframes, packet_bufX + CDO, net_period_up - CDO );
unsigned short len = htons(encoded_bytes);
memcpy(packet_bufX, &len, CDO);
src_node = jack_slist_next( src_node );
} else if (jack_port_is_midi (porttype)) {
// encode midi events from port to packet
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_up / 2;
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
}
packet_bufX = (packet_bufX + net_period_up);
node = jack_slist_next (node);
chn++;
}
}
#endif

/* Wrapper functions with bitdepth argument... */
void
render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
@@ -1358,6 +1450,10 @@ render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t
#if HAVE_CELT
else if (bitdepth == CELT_MODE)
render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
#endif
#if HAVE_OPUS
else if (bitdepth == OPUS_MODE)
render_payload_to_jack_ports_opus (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
#endif
else
render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
@@ -1373,6 +1469,10 @@ render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *play
#if HAVE_CELT
else if (bitdepth == CELT_MODE)
render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
#endif
#if HAVE_OPUS
else if (bitdepth == OPUS_MODE)
render_jack_ports_to_payload_opus (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
#endif
else
render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);


+ 1
- 0
common/netjack_packet.h View File

@@ -40,6 +40,7 @@ extern "C"
// The Packet Header.

#define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression
#define OPUS_MODE 999 // Magic bitdepth value that indicates OPUS compression
#define MASTER_FREEWHEELS 0x80000000

typedef struct _jacknet_packet_header jacknet_packet_header;


+ 23
- 9
common/shm.c View File

@@ -5,6 +5,7 @@
* - common (interface-independent) code
* - POSIX implementation
* - System V implementation
* - Windows implementation
*
* The implementation used is determined by whether USE_POSIX_SHM was
* set in the ./configure step.
@@ -12,7 +13,8 @@

/*
Copyright (C) 2001-2003 Paul Davis

Copyright (C) 2005-2012 Grame
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
@@ -1167,7 +1169,7 @@ jack_access_registry (jack_shm_info_t *ri)
}
}

if ((ri->attached_at = shmat (registry_id, 0, 0)) < 0) {
if ((ri->ptr.attached_at = shmat (registry_id, 0, 0)) < 0) {
jack_error ("Cannot attach shm registry segment (%s)",
strerror (errno));
return EINVAL;
@@ -1175,7 +1177,7 @@ jack_access_registry (jack_shm_info_t *ri)

/* set up global pointers */
ri->index = JACK_SHM_REGISTRY_INDEX;
jack_shm_header = ri->attached_at;
jack_shm_header = ri->ptr.attached_at;
jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1);
return 0;
}
@@ -1199,7 +1201,7 @@ jack_create_registry (jack_shm_info_t *ri)
return errno;
}

if ((ri->attached_at = shmat (registry_id, 0, 0)) < 0) {
if ((ri->ptr.attached_at = shmat (registry_id, 0, 0)) < 0) {
jack_error ("Cannot attach shm registry segment (%s)",
strerror (errno));
return EINVAL;
@@ -1207,7 +1209,7 @@ jack_create_registry (jack_shm_info_t *ri)

/* set up global pointers */
ri->index = JACK_SHM_REGISTRY_INDEX;
jack_shm_header = ri->attached_at;
jack_shm_header = ri->ptr.attached_at;
jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1);

/* initialize registry contents */
@@ -1226,8 +1228,8 @@ void
jack_release_shm (jack_shm_info_t* si)
{
/* registry may or may not be locked */
if (si->attached_at != MAP_FAILED) {
shmdt (si->attached_at);
if (si->ptr.attached_at != MAP_FAILED) {
shmdt (si->ptr.attached_at);
}
}

@@ -1261,7 +1263,7 @@ jack_shmalloc (const char* name_not_used, jack_shmsize_t size,
registry->id = shmid;
registry->allocator = getpid();
si->index = registry->index;
si->attached_at = MAP_FAILED; /* not attached */
si->ptr.attached_at = MAP_FAILED; /* not attached */
rc = 0;

} else {
@@ -1277,7 +1279,19 @@ jack_shmalloc (const char* name_not_used, jack_shmsize_t size,
int
jack_attach_shm (jack_shm_info_t* si)
{
if ((si->attached_at = shmat (jack_shm_registry[si->index].id, 0, 0)) < 0) {
if ((si->ptr.attached_at = shmat (jack_shm_registry[si->index].id, 0, 0)) < 0) {
jack_error ("Cannot attach shm segment (%s)",
strerror (errno));
jack_release_shm_info (si->index);
return -1;
}
return 0;
}

int
jack_attach_shm_read (jack_shm_info_t* si)
{
if ((si->ptr.attached_at = shmat (jack_shm_registry[si->index].id, 0, SHM_RDONLY)) < 0) {
jack_error ("Cannot attach shm segment (%s)",
strerror (errno));
jack_release_shm_info (si->index);


+ 34
- 1
common/shm.h View File

@@ -1,3 +1,36 @@
/* This module provides a set of abstract shared memory interfaces
* with support using both System V and POSIX shared memory
* implementations. The code is divided into three sections:
*
* - common (interface-independent) code
* - POSIX implementation
* - System V implementation
* - Windows implementation
*
* The implementation used is determined by whether USE_POSIX_SHM was
* set in the ./configure step.
*/

/*
Copyright (C) 2001-2003 Paul Davis
Copyright (C) 2005-2012 Grame

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

#ifndef __jack_shm_h__
#define __jack_shm_h__

@@ -38,7 +71,7 @@ extern "C"
typedef char shm_name_t[SHM_NAME_MAX];
typedef shm_name_t jack_shm_id_t;

#elif WIN32 // TO CHECK
#elif WIN32
#define NAME_MAX 255
#ifndef SHM_NAME_MAX
#define SHM_NAME_MAX NAME_MAX


+ 3
- 3
common/wscript View File

@@ -68,7 +68,7 @@ def build(bld):
]

includes = ['.', './jack', '..']
uselib = ["PTHREAD", "CELT"]
uselib = ["PTHREAD", "CELT", "OPUS"]

if bld.env['IS_LINUX']:
common_libsources += [
@@ -193,7 +193,7 @@ def build(bld):
netlib.includes = includes
netlib.name = 'netlib'
netlib.target = 'jacknet'
netlib.use = ['SAMPLERATE', 'CELT', 'PTHREAD' , 'RT']
netlib.use = ['SAMPLERATE', 'CELT', 'OPUS', 'PTHREAD' , 'RT']
netlib.install_path = '${LIBDIR}'
netlib.source = [
'JackNetAPI.cpp',
@@ -226,7 +226,7 @@ def build(bld):
clientlib.defines = 'HAVE_CONFIG_H'
clientlib.use = uselib
clientlib.install_path = '${LIBDIR}'
if bld.env['BUILD_JACKDBUS'] == True and bld.env['BUILD_JACKD'] == False:
if bld.env['AUTOSTART_METHOD'] == "dbus":
clientlib.use.append('DBUS-1')
clientlib.includes = includes
clientlib.name = 'clientlib'


+ 3
- 0
dbus/audio_reserve.c View File

@@ -76,6 +76,8 @@ SERVER_EXPORT bool audio_acquire(const char * device_name)

assert(gReserveCount < DEVICE_MAX);

dbus_error_init(&error);

if ((ret= rd_acquire(
&gReservedDevice[gReserveCount].reserved_device,
gConnection,
@@ -86,6 +88,7 @@ SERVER_EXPORT bool audio_acquire(const char * device_name)
&error)) < 0) {

jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret)));
dbus_error_free(&error);
return false;
}



+ 3
- 0
dbus/controller.c View File

@@ -377,6 +377,8 @@ on_device_acquire(const char * device_name)
int ret;
DBusError error;

dbus_error_init(&error);

ret = rd_acquire(
&g_reserved_device[g_device_count].reserved_device,
g_connection,
@@ -388,6 +390,7 @@ on_device_acquire(const char * device_name)
if (ret < 0)
{
jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret)));
dbus_error_free(&error);
return false;
}



+ 62
- 18
dbus/reserve.c View File

@@ -31,6 +31,11 @@
#include <stdint.h>

#include "reserve.h"
#include "jack/control.h"

#define RESERVE_ERROR_NO_MEMORY "org.freedesktop.ReserveDevice1.Error.NoMemory"
#define RESERVE_ERROR_PROTOCOL_VIOLATION "org.freedesktop.ReserveDevice1.Error.Protocol"
#define RESERVE_ERROR_RELEASE_DENIED "org.freedesktop.ReserveDevice1.Error.ReleaseDenied"

struct rd_device {
int ref;
@@ -371,34 +376,51 @@ int rd_acquire(
dbus_bool_t good;
vtable.message_function = object_handler;

if (!error)
if (!error) {
error = &_error;
dbus_error_init(error);
}

dbus_error_init(error);

if (!_d)
return -EINVAL;
if (!_d) {
assert(0);
r = -EINVAL;
goto fail;
}

if (!connection)
return -EINVAL;
if (!connection) {
assert(0);
r = -EINVAL;
goto fail;
}

if (!device_name)
return -EINVAL;
if (!device_name) {
assert(0);
r = -EINVAL;
goto fail;
}

if (!request_cb && priority != INT32_MAX)
return -EINVAL;
if (!request_cb && priority != INT32_MAX) {
assert(0);
r = -EINVAL;
goto fail;
}

if (!(d = (rd_device *)calloc(sizeof(rd_device), 1)))
return -ENOMEM;
if (!(d = (rd_device *)calloc(sizeof(rd_device), 1))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for rd_device struct");
r = -ENOMEM;
goto fail;
}

d->ref = 1;

if (!(d->device_name = strdup(device_name))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot duplicate device name string");
r = -ENOMEM;
goto fail;
}

if (!(d->application_name = strdup(application_name))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot duplicate application name string");
r = -ENOMEM;
goto fail;
}
@@ -408,12 +430,14 @@ int rd_acquire(
d->request_cb = request_cb;

if (!(d->service_name = (char*)malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for service name string");
r = -ENOMEM;
goto fail;
}
sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name);

if (!(d->object_path = (char*)malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for object path string");
r = -ENOMEM;
goto fail;
}
@@ -425,20 +449,28 @@ int rd_acquire(
DBUS_NAME_FLAG_DO_NOT_QUEUE|
(priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0),
error)) < 0) {
jack_error("dbus_bus_request_name() failed. (1)");
r = -EIO;
goto fail;
}

if (k == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER || k == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)
switch (k) {
case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
goto success;

if (k != DBUS_REQUEST_NAME_REPLY_EXISTS) {
case DBUS_REQUEST_NAME_REPLY_EXISTS:
break;
case DBUS_REQUEST_NAME_REPLY_IN_QUEUE : /* DBUS_NAME_FLAG_DO_NOT_QUEUE was specified */
default: /* unknown reply returned */
jack_error("request name reply with unexpected value %d.", k);
assert(0);
r = -EIO;
goto fail;
}

if (priority <= INT32_MIN) {
r = -EBUSY;
dbus_set_error(error, RESERVE_ERROR_RELEASE_DENIED, "Device reservation request with priority %"PRIi32" denied for \"%s\"", priority, device_name);
goto fail;
}

@@ -447,6 +479,7 @@ int rd_acquire(
d->object_path,
"org.freedesktop.ReserveDevice1",
"RequestRelease"))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for RequestRelease method call");
r = -ENOMEM;
goto fail;
}
@@ -455,6 +488,7 @@ int rd_acquire(
m,
DBUS_TYPE_INT32, &d->priority,
DBUS_TYPE_INVALID)) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot append args for RequestRelease method call");
r = -ENOMEM;
goto fail;
}
@@ -469,10 +503,12 @@ int rd_acquire(
dbus_error_has_name(error, DBUS_ERROR_UNKNOWN_METHOD) ||
dbus_error_has_name(error, DBUS_ERROR_NO_REPLY)) {
/* This must be treated as denied. */
jack_info("Device reservation request with priority %"PRIi32" denied for \"%s\": %s (%s)", priority, device_name, error->name, error->message);
r = -EBUSY;
goto fail;
}

jack_error("dbus_connection_send_with_reply_and_block(RequestRelease) failed.");
r = -EIO;
goto fail;
}
@@ -482,11 +518,13 @@ int rd_acquire(
error,
DBUS_TYPE_BOOLEAN, &good,
DBUS_TYPE_INVALID)) {
jack_error("RequestRelease() reply is invalid.");
r = -EIO;
goto fail;
}

if (!good) {
dbus_set_error(error, RESERVE_ERROR_RELEASE_DENIED, "Device reservation request with priority %"PRIi32" denied for \"%s\" via RequestRelease()", priority, device_name);
r = -EBUSY;
goto fail;
}
@@ -498,11 +536,14 @@ int rd_acquire(
(priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0)|
DBUS_NAME_FLAG_REPLACE_EXISTING,
error)) < 0) {
jack_error("dbus_bus_request_name() failed. (2)");
r = -EIO;
goto fail;
}

if (k != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
/* this is racy, another contender may have acquired the device */
dbus_set_error(error, RESERVE_ERROR_PROTOCOL_VIOLATION, "request name reply is not DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER but %d.", k);
r = -EIO;
goto fail;
}
@@ -510,11 +551,13 @@ int rd_acquire(
success:
d->owning = 1;

if (!(dbus_connection_register_object_path(
if (!(dbus_connection_try_register_object_path(
d->connection,
d->object_path,
&vtable,
d))) {
d,
error))) {
jack_error("cannot register object path \"%s\": %s", d->object_path, error->message);
r = -ENOMEM;
goto fail;
}
@@ -526,6 +569,7 @@ success:
filter_handler,
d,
NULL)) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot add filter");
r = -ENOMEM;
goto fail;
}


+ 5
- 1
dbus/sigsegv.c View File

@@ -107,7 +107,9 @@ static void signal_segv(int signum, siginfo_t* info, void*ptr) {
#if !defined(__alpha__) && !defined(__ia64__) && !defined(__FreeBSD_kernel__) && !defined(__arm__) && !defined(__hppa__) && !defined(__sh__)
for(i = 0; i < NGREG; i++)
jack_error("reg[%02d] = 0x" REGFORMAT, i,
#if defined(__powerpc__)
#if defined(__powerpc64__)
ucontext->uc_mcontext.gp_regs[i]
#elif defined(__powerpc__)
ucontext->uc_mcontext.uc_regs[i]
#elif defined(__sparc__) && defined(__arch64__)
ucontext->uc_mcontext.mc_gregs[i]
@@ -177,7 +179,9 @@ int setup_sigsegv() {

memset(&action, 0, sizeof(action));
action.sa_sigaction = signal_segv;
#ifdef SA_SIGINFO
action.sa_flags = SA_SIGINFO;
#endif
if(sigaction(SIGSEGV, &action, NULL) < 0) {
jack_error("sigaction failed. errno is %d (%s)", errno, strerror(errno));
return 0;


+ 1
- 1
dbus/wscript View File

@@ -67,7 +67,7 @@ def build(bld):
]
obj.use = ['serverlib']
if bld.env['IS_LINUX']:
obj.use += ['PTHREAD', 'DL', 'RT', 'DBUS-1', 'EXPAT']
obj.use += ['PTHREAD', 'DL', 'RT', 'DBUS-1', 'EXPAT', 'STDC++']
if bld.env['IS_MACOSX']:
obj.use += ['PTHREAD', 'DL', 'DBUS-1', 'EXPAT']
obj.target = 'jackdbus'


+ 2
- 2
example-clients/control.c View File

@@ -27,7 +27,7 @@ static int Jack_Graph_Order_Callback(void *arg)
for (i = 0; ports[i]; ++i) {
printf("name: %s\n", ports[i]);
}
free(ports);
jack_free(ports);
}

ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
@@ -35,7 +35,7 @@ static int Jack_Graph_Order_Callback(void *arg)
for (i = 0; ports[i]; ++i) {
printf("name: %s\n", ports[i]);
}
free(ports);
jack_free(ports);
}

return 0;


+ 39
- 1
example-clients/jack_control View File

@@ -116,17 +116,20 @@ def main():
print " dp - get parameters of currently selected driver"
print " dpd <param> - get long description for driver parameter"
print " dps <param> <value> - set driver parameter"
print " dpr <param> - reset driver parameter to its default value"
print " asd <driver> - add slave driver"
print " rsd <driver> - remove slave driver"
print " il - get list of available internals"
print " ip <name> - get parameters of given internal"
print " ipd <name> <param> - get long description for internal parameter"
print " ips <name> <param> <value> - set internal parameter"
print " ipr <name> <param> - reset internal parameter to its default value"
print " iload <name> - load internal"
print " iunload <name> - unload internal"
print " ep - get engine parameters"
print " epd <param> - get long description for engine parameter"
print " eps <param> <value> - set engine parameter"
print " epr <param> - reset engine parameter to its default value"
sys.exit(0)
bus = dbus.SessionBus()
@@ -213,6 +216,16 @@ def main():

type_char, name, short_descr, long_descr = configure_iface.GetParameterInfo(['driver', param])
configure_iface.SetParameterValue(['driver', param], python_type_to_jackdbus_type(value, type_char))
elif arg == 'dpr':
if index >= len(sys.argv):
print "driver parameter reset command requires parameter name argument"
sys.exit()

param = sys.argv[index]
index += 1

print "--- driver param reset \"%s\"" % param
configure_iface.ResetParameterValue(['driver', param])
elif arg == 'ep':
print "--- get engine parameters (type:isset:default:value)"
get_parameters(configure_iface, ['engine'])
@@ -242,6 +255,18 @@ def main():

type_char, name, short_descr, long_descr = configure_iface.GetParameterInfo(['engine', param])
configure_iface.SetParameterValue(['engine', param], python_type_to_jackdbus_type(value, type_char))
elif arg == 'epr':
if index >= len(sys.argv):
print "engine parameter reset command requires parameter name"
sys.exit()

param = sys.argv[index]
index += 1

print "--- engine param reset \"%s\"" % param

type_char, name, short_descr, long_descr = configure_iface.GetParameterInfo(['engine', param])
configure_iface.ResetParameterValue(['engine', param])
elif arg == 'il':
print "--- internals list"
is_leaf, internals = configure_iface.ReadContainer(['internals'])
@@ -273,7 +298,7 @@ def main():
print long_descr
elif arg == 'ips':
if index + 2 >= len(sys.argv):
print "get internal parameter long description command requires internal, parameter name and value arguments"
print "internal parameter set command requires internal, parameter name and value arguments"
sys.exit()

internal_name = sys.argv[index]
@@ -287,6 +312,19 @@ def main():

type_char, name, short_descr, long_descr = configure_iface.GetParameterInfo(['internals', internal_name, param])
configure_iface.SetParameterValue(['internals', internal_name, param], python_type_to_jackdbus_type(value, type_char))
elif arg == 'ipr':
if index + 1 >= len(sys.argv):
print "reset internal parameter command requires internal and parameter name arguments"
sys.exit()

internal_name = sys.argv[index]
index += 1
param = sys.argv[index]
index += 1

print "--- internal param reset \"%s\"" % param

configure_iface.ResetParameterValue(['internals', internal_name, param])
elif arg == 'iload':
print "--- load internal"



+ 1
- 1
example-clients/metro.c View File

@@ -154,7 +154,7 @@ main (int argc, char *argv[])
{0, 0, 0, 0}
};

while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) {
switch (opt) {
case 'f':
if ((freq = atoi (optarg)) <= 0) {


+ 1
- 1
example-clients/netmaster.c View File

@@ -73,7 +73,7 @@ main (int argc, char *argv[])
{0, 0, 0, 0}
};

while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) {

switch (opt) {



+ 44
- 3
example-clients/netsource.c View File

@@ -62,6 +62,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <celt/celt.h>
#endif

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#include <math.h>

JSList *capture_ports = NULL;
@@ -147,6 +152,16 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL );
capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
#endif
#endif
} else if (bitdepth == 999) {
#if HAVE_OPUS
int err;
OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate( client ), jack_get_buffer_size(client), &err);
if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); }
OpusCustomDecoder *decoder = opus_custom_decoder_create(opus_mode, 1, &err);
if (err != OPUS_OK) { printf("OPUS DECODER FAILED\n"); }
opus_custom_decoder_init(decoder, opus_mode, 1);
capture_srcs = jack_slist_append(capture_srcs, decoder);
#endif
} else {
#if HAVE_SAMPLERATE
@@ -189,6 +204,22 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL );
playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
#endif
#endif
} else if( bitdepth == 999 ) {
#if HAVE_OPUS
const int kbps = factor;
printf("new opus encoder %d kbps\n", kbps);
int err;
OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate (client), jack_get_buffer_size(client), &err ); // XXX free me
if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); }
OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err );
if (err != OPUS_OK) { printf("OPUS ENCODER FAILED\n"); }
opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
opus_custom_encoder_init(oe, opus_mode, 1);
playback_srcs = jack_slist_append(playback_srcs, oe);
#endif
} else {
#if HAVE_SAMPLERATE
@@ -269,7 +300,7 @@ process (jack_nframes_t nframes, void *arg)
uint32_t *rx_packet_ptr;
jack_time_t packet_recv_timestamp;

if( bitdepth == 1000 )
if( bitdepth == 1000 || bitdepth == 999)
net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
else
net_period = (float) nframes / (float) factor;
@@ -519,6 +550,7 @@ printUsage ()
" -B <bind port> - reply port, for use in NAT environments\n"
" -b <bitdepth> - Set transport to use 16bit or 8bit\n"
" -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n"
" -P <kbits> - Use Opus encoding with <kbits> kbits per channel\n"
" -m <mtu> - Assume this mtu for the link\n"
" -R <N> - Redundancy: send out packets N times.\n"
" -e - skip host-to-network endianness conversion\n"
@@ -564,7 +596,7 @@ main (int argc, char *argv[])
sprintf(client_name, "netjack");
sprintf(peer_ip, "localhost");

while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1) {
while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:P:")) != -1) {
switch (c) {
case 'h':
printUsage();
@@ -613,6 +645,15 @@ main (int argc, char *argv[])
#else
printf( "not built with celt support\n" );
exit(10);
#endif
break;
case 'P':
#if HAVE_OPUS
bitdepth = 999;
factor = atoi (optarg);
#else
printf( "not built with opus support\n" );
exit(10);
#endif
break;
case 'm':
@@ -689,7 +730,7 @@ main (int argc, char *argv[])

alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);

if( bitdepth == 1000 )
if( bitdepth == 1000 || bitdepth == 999)
net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
else
net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor);


+ 2
- 1
example-clients/server_control.cpp View File

@@ -153,9 +153,10 @@ int main(int argc, char *argv[])
struct option long_options[] = {
{"driver", 1, 0, 'd'},
{"client", 1, 0, 'c'},
{0, 0, 0, 0}
};

while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) {
switch (opt) {
case 'd':
driver_name = optarg;


+ 1
- 1
example-clients/simple_client.c View File

@@ -191,7 +191,7 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot connect output ports\n");
}

free (ports);
jack_free (ports);
/* install a signal handler to properly quits jack client */
#ifdef WIN32


+ 2
- 2
example-clients/tw.c View File

@@ -231,7 +231,7 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot connect input ports\n");
}

free (ports);
jack_free (ports);

ports = jack_get_ports (client, NULL, NULL,
JackPortIsPhysical|JackPortIsInput);
@@ -244,7 +244,7 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot connect output ports\n");
}

free (ports);
jack_free (ports);

/* install a signal handler to properly quits jack client */
signal(SIGQUIT, signal_handler);


+ 13
- 14
example-clients/wscript View File

@@ -50,7 +50,7 @@ def configure(conf):
#if conf.is_defined('HAVE_READLINE'):
# conf.env['LIB_READLINE'] = ['readline']

conf.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] = bool(conf.env['LIB_READLINE']) and bool(conf.env['LIB_NCURSES'])
conf.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] = bool(conf.env['LIB_READLINE'])

conf.env['BUILD_EXAMPLE_CLIENT_REC'] = conf.is_defined('HAVE_SNDFILE')

@@ -65,7 +65,7 @@ def build(bld):
os_incdir = ['../solaris', '../posix']
for example_program, example_program_source in list(example_programs.items()):
if example_program == 'jack_server_control':
use = ['serverlib']
use = ['serverlib', 'STDC++']
elif example_program == 'jack_net_slave':
if not bld.env['BUILD_NETLIB']:
continue
@@ -86,10 +86,9 @@ def build(bld):
#prog.env.append_value("LINKFLAGS", "-arch i386 -arch ppc -arch x86_64")
prog.env.append_value("LINKFLAGS", "")
if bld.env['IS_LINUX']:
prog.use += ['RT']
prog.env.append_value("LINKFLAGS", "-lm")
prog.use += ['RT', 'M']
if bld.env['IS_SUN']:
prog.env.append_value("LINKFLAGS", "-lm")
prog.use += ['M']

prog.target = example_program
@@ -103,9 +102,9 @@ def build(bld):
#prog.env.append_value("LINKFLAGS", "-arch i386 -arch ppc -arch x86_64")
prog.env.append_value("LINKFLAGS", "")
if bld.env['IS_LINUX']:
prog.use += ['RT', 'READLINE', 'NCURSES']
prog.use += ['RT', 'READLINE']
if bld.env['IS_MACOSX']:
prog.use += ['READLINE', 'NCURSES']
prog.use += ['READLINE']
prog.target = 'jack_transport'

if bld.env['BUILD_EXAMPLE_CLIENT_REC']:
@@ -126,26 +125,26 @@ def build(bld):

if bld.env['IS_LINUX'] or bld.env['IS_MACOSX']:
prog = bld(features = 'c cprogram')
prog.includes = os_incdir + ['../common/jack', '../common']
prog.includes = os_incdir + ['.', '..', '../common/jack', '../common']
prog.source = ['netsource.c', '../common/netjack_packet.c']
prog.env.append_value("CFLAGS", "-DNO_JACK_ERROR")
prog.use = ['CELT', 'SAMPLERATE']
prog.use = ['clientlib']
prog.use = ['CELT', 'SAMPLERATE', 'OPUS', 'M', 'clientlib']
prog.target = 'jack_netsource'
prog.defines = ['HAVE_CONFIG_H']

if bld.env['IS_LINUX'] and bld.env['BUILD_EXAMPLE_ALSA_IO']:
prog = bld(features = 'c cprogram')
prog.includes = os_incdir + ['../common/jack', '../common']
prog.source = ['alsa_in.c', '../common/memops.c']
prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR")
prog.use = ['clientlib', 'ALSA', 'SAMPLERATE']
prog.env.append_value("CFLAGS", "-DNO_JACK_ERROR")
prog.use = ['clientlib', 'ALSA', 'SAMPLERATE', 'M']
prog.target = 'alsa_in'

prog = bld(features = 'c cprogram')
prog.includes = os_incdir + ['../common/jack', '../common']
prog.source = ['alsa_out.c', '../common/memops.c']
prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR")
prog.use = ['clientlib', 'ALSA', 'SAMPLERATE']
prog.env.append_value("CFLAGS", "-DNO_JACK_ERROR")
prog.use = ['clientlib', 'ALSA', 'SAMPLERATE', 'M']
prog.target = 'alsa_out'

for example_lib, example_lib_source in list(example_libs.items()):


+ 6
- 0
linux/alsa/JackAlsaAdapter.cpp View File

@@ -54,8 +54,14 @@ namespace Jack
fPlaybackChannels = param->value.ui;
break;
case 'C':
if (strncmp(param->value.str,"none",4) != 0) {
fAudioInterface.fCaptureName = strdup ( param->value.str );
}
break;
case 'P':
if (strncmp(param->value.str,"none",4) != 0) {
fAudioInterface.fPlaybackName = strdup ( param->value.str );
}
break;
case 'D':
break;


+ 10
- 3
linux/alsa/JackAlsaAdapter.h View File

@@ -130,6 +130,8 @@ namespace Jack
snd_pcm_access_t fSampleAccess;

//channels
const char* fCaptureName;
const char* fPlaybackName;
unsigned int fCardInputs;
unsigned int fCardOutputs;

@@ -182,6 +184,8 @@ namespace Jack
fInputParams = 0;
fOutputParams = 0;
fPeriod = 2;
fCaptureName = NULL;
fPlaybackName = NULL;

fInputCardBuffer = 0;
fOutputCardBuffer = 0;
@@ -200,6 +204,8 @@ namespace Jack
{
fInputCardBuffer = 0;
fOutputCardBuffer = 0;
fCaptureName = NULL;
fPlaybackName = NULL;

for ( int i = 0; i < 256; i++ )
{
@@ -216,8 +222,8 @@ namespace Jack
int open()
{
//open input/output streams
check_error ( snd_pcm_open ( &fInputDevice, fCardName, SND_PCM_STREAM_CAPTURE, 0 ) );
check_error ( snd_pcm_open ( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ) );
check_error ( snd_pcm_open ( &fInputDevice, (fCaptureName == NULL) ? fCardName : fCaptureName, SND_PCM_STREAM_CAPTURE, 0 ) );
check_error ( snd_pcm_open ( &fOutputDevice, (fPlaybackName == NULL) ? fCardName : fPlaybackName, SND_PCM_STREAM_PLAYBACK, 0 ) );

//get hardware input parameters
check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) );
@@ -523,6 +529,7 @@ namespace Jack
fCardInputs, fCardOutputs,
fFrequency, fBuffering,
snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ) );
snd_ctl_close(ctl_handle);
}

/**
@@ -551,7 +558,7 @@ namespace Jack
printHWParams ( fInputParams );
if ( fSoftOutputs > 0 )
printHWParams ( fOutputParams );
snd_ctl_close(ctl_handle);
return 0;
}



+ 47
- 36
linux/alsa/JackAlsaDriver.cpp View File

@@ -31,7 +31,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <regex.h>
#include <string.h>

#include "JackAlsaDriver.h"
@@ -172,30 +171,31 @@ int JackAlsaDriver::Detach()
return JackAudioDriver::Detach();
}

static char* get_control_device_name(const char * device_name)
extern "C" char* get_control_device_name(const char * device_name)
{
char * ctl_name;
regex_t expression;
const char * comma;

regcomp(&expression, "(plug)?hw:[0-9](,[0-9])?", REG_ICASE | REG_EXTENDED);
/* the user wants a hw or plughw device, the ctl name
* should be hw:x where x is the card identification.
* We skip the subdevice suffix that starts with comma */

if (!regexec(&expression, device_name, 0, NULL, 0)) {
/* the user wants a hw or plughw device, the ctl name
* should be hw:x where x is the card number */

char tmp[5];
strncpy(tmp, strstr(device_name, "hw"), 4);
tmp[4] = '\0';
jack_info("control device %s",tmp);
ctl_name = strdup(tmp);
} else {
ctl_name = strdup(device_name);
if (strncasecmp(device_name, "plughw:", 7) == 0) {
/* skip the "plug" prefix" */
device_name += 4;
}

regfree(&expression);

if (ctl_name == NULL) {
jack_error("strdup(\"%s\") failed.", ctl_name);
comma = strchr(device_name, ',');
if (comma == NULL) {
ctl_name = strdup(device_name);
if (ctl_name == NULL) {
jack_error("strdup(\"%s\") failed.", device_name);
}
} else {
ctl_name = strndup(device_name, comma - device_name);
if (ctl_name == NULL) {
jack_error("strndup(\"%s\", %u) failed.", device_name, (unsigned int)(comma - device_name));
}
}

return ctl_name;
@@ -278,16 +278,22 @@ int JackAlsaDriver::Open(jack_nframes_t nframes,
int playback_card = card_to_num(playback_driver_name);
char audio_name[32];

snprintf(audio_name, sizeof(audio_name), "Audio%d", capture_card);
if (!JackServerGlobals::on_device_acquire(audio_name)) {
jack_error("Audio device %s cannot be acquired...", capture_driver_name);
return -1;
if (capture_card >= 0) {
snprintf(audio_name, sizeof(audio_name), "Audio%d", capture_card);
if (!JackServerGlobals::on_device_acquire(audio_name)) {
jack_error("Audio device %s cannot be acquired...", capture_driver_name);
return -1;
}
}

if (playback_card != capture_card) {
if (playback_card >= 0 && playback_card != capture_card) {
snprintf(audio_name, sizeof(audio_name), "Audio%d", playback_card);
if (!JackServerGlobals::on_device_acquire(audio_name)) {
jack_error("Audio device %s cannot be acquired...", playback_driver_name);
if (capture_card >= 0) {
snprintf(audio_name, sizeof(audio_name), "Audio%d", capture_card);
JackServerGlobals::on_device_release(audio_name);
}
return -1;
}
}
@@ -579,6 +585,7 @@ enum_alsa_devices()
if (snd_ctl_open(&handle, card_id, 0) >= 0 &&
snd_ctl_card_info(handle, info) >= 0)
{
snprintf(card_id, sizeof(card_id), "hw:%s", snd_ctl_card_info_get_id(info));
fill_device(&constraint_ptr, &array_size, card_id, snd_ctl_card_info_get_name(info));

device_no = -1;
@@ -731,13 +738,13 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor ()

desc = jack_driver_descriptor_construct("alsa", JackDriverMaster, "Linux ALSA API based audio backend", &filler);

strcpy(value.str, "hw:0");
jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, enum_alsa_devices(), "ALSA device name", NULL);

strcpy(value.str, "none");
jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set device", NULL);
jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Provide playback ports. Optionally set device", NULL);

strcpy(value.str, "hw:0");
jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, enum_alsa_devices(), "ALSA device name", NULL);

value.ui = 48000U;
jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);

@@ -778,9 +785,9 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor ()
" s - shaped\n"
" t - triangular");

value.i = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamInt, &value, NULL, "Number of capture channels (defaults to hardware max)", NULL);
jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamInt, &value, NULL, "Number of playback channels (defaults to hardware max)", NULL);
value.ui = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Number of capture channels (defaults to hardware max)", NULL);
jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Number of playback channels (defaults to hardware max)", NULL);

value.i = FALSE;
jack_driver_descriptor_add_parameter(desc, &filler, "shorts", 'S', JackDriverParamBool, &value, NULL, "Try 16-bit samples before 32-bit", NULL);
@@ -859,10 +866,12 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke
break;

case 'd':
playback_pcm_name = strdup (param->value.str);
capture_pcm_name = strdup (param->value.str);
jack_log("playback device %s", playback_pcm_name);
jack_log("capture device %s", capture_pcm_name);
if (strcmp (param->value.str, "none") != 0) {
playback_pcm_name = strdup (param->value.str);
capture_pcm_name = strdup (param->value.str);
jack_log("playback device %s", playback_pcm_name);
jack_log("capture device %s", capture_pcm_name);
}
break;

case 'H':
@@ -889,8 +898,9 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke

case 'n':
user_nperiods = param->value.ui;
if (user_nperiods < 2) /* enforce minimum value */
if (user_nperiods < 2) { /* enforce minimum value */
user_nperiods = 2;
}
break;

case 's':
@@ -974,8 +984,9 @@ void SetTime(jack_time_t time)
int Restart()
{
int res;
if ((res = g_alsa_driver->Stop()) == 0)
if ((res = g_alsa_driver->Stop()) == 0) {
res = g_alsa_driver->Start();
}
return res;
}



+ 1
- 3
linux/alsa/JackAlsaDriver.h View File

@@ -39,15 +39,13 @@ class JackAlsaDriver : public JackAudioDriver
private:

jack_driver_t* fDriver;
int fReservedCaptureDevice;
int fReservedPlaybackDevice;

void UpdateLatencies();

public:

JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
: JackAudioDriver(name, alias, engine, table),fDriver(NULL),fReservedCaptureDevice(-1),fReservedPlaybackDevice(-1)
: JackAudioDriver(name, alias, engine, table),fDriver(NULL)
{}
virtual ~JackAlsaDriver()
{}


+ 3
- 17
linux/alsa/alsa_driver.c View File

@@ -32,7 +32,6 @@
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <regex.h>
#include <string.h>

#include "alsa_driver.h"
@@ -137,30 +136,18 @@ alsa_driver_check_capabilities (alsa_driver_t *driver)
return 0;
}

char* get_control_device_name(const char * device_name);

static int
alsa_driver_check_card_type (alsa_driver_t *driver)
{
int err;
snd_ctl_card_info_t *card_info;
char * ctl_name;
regex_t expression;

snd_ctl_card_info_alloca (&card_info);

regcomp(&expression,"(plug)?hw:[0-9](,[0-9])?",REG_ICASE|REG_EXTENDED);

if (!regexec(&expression,driver->alsa_name_playback,0,NULL,0)) {
/* the user wants a hw or plughw device, the ctl name
* should be hw:x where x is the card number */

char tmp[5];
strncpy(tmp,strcasestr(driver->alsa_name_playback,"hw"),4);
tmp[4]='\0';
jack_info("control device %s",tmp);
ctl_name = strdup(tmp);
} else {
ctl_name = strdup(driver->alsa_name_playback);
}
ctl_name = get_control_device_name(driver->alsa_name_playback);

// XXX: I don't know the "right" way to do this. Which to use
// driver->alsa_name_playback or driver->alsa_name_capture.
@@ -175,7 +162,6 @@ alsa_driver_check_card_type (alsa_driver_t *driver)

driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info));

regfree(&expression);
free(ctl_name);

return alsa_driver_check_capabilities (driver);


+ 2
- 2
linux/wscript View File

@@ -38,9 +38,9 @@ def build(bld):
jackd.use = ['serverlib']
if bld.env['IS_LINUX'] and bld.env['BUILD_JACKDBUS']:
jackd.source += ['../dbus/reserve.c', '../dbus/audio_reserve.c']
jackd.use += ['PTHREAD', 'DL', 'RT', 'DBUS-1']
jackd.use += ['PTHREAD', 'DL', 'RT', 'M', 'STDC++', 'DBUS-1']
else:
jackd.use += ['PTHREAD', 'DL', 'RT']
jackd.use += ['PTHREAD', 'DL', 'RT', 'M', 'STDC++']
jackd.target = 'jackd'
create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp')


+ 2
- 2
macosx/Jack-Info.plist View File

@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>Jackservermp</string>
<key>CFBundleGetInfoString</key>
<string>Jackdmp 1.9.9, @03-11 Paul Davis, Grame</string>
<string>Jackdmp 1.9.9.5, @03-12 Paul Davis, Grame</string>
<key>CFBundleIdentifier</key>
<string>com.grame.Jackmp</string>
<key>CFBundleInfoDictionaryVersion</key>
@@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.9.9</string>
<string>1.9.9.5</string>
</dict>
</plist>

+ 11
- 7
macosx/Jackdmp.xcodeproj/project.pbxproj View File

@@ -8737,6 +8737,7 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = "";
HEADER_SEARCH_PATHS = (
../macosx,
/opt/local/include,
.,
../posix,
@@ -8787,6 +8788,7 @@
GCC_MODEL_TUNING = G4;
GCC_PREPROCESSOR_DEFINITIONS = "";
HEADER_SEARCH_PATHS = (
../macosx,
/opt/local/include,
.,
../posix,
@@ -9750,7 +9752,7 @@
../common/jack,
);
INFOPLIST_FILE = "Jack-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = (
@@ -9935,7 +9937,7 @@
../common/jack,
);
INFOPLIST_FILE = "Jack-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = (
@@ -13629,7 +13631,7 @@
../common/jack,
);
INFOPLIST_FILE = "Jack-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = (
@@ -14461,7 +14463,7 @@
../common/jack,
);
INFOPLIST_FILE = "Jack-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = (
@@ -14640,7 +14642,7 @@
../common/jack,
);
INFOPLIST_FILE = "Jack-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = (
@@ -16431,7 +16433,7 @@
../common/jack,
);
INFOPLIST_FILE = "Jack-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
LIBRARY_SEARCH_PATHS = (
/opt/local/lib,
/usr/lib/gcc/darwin/3.3,
@@ -16954,7 +16956,7 @@
../common/jack,
);
INFOPLIST_FILE = "Jack-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = (
@@ -17908,6 +17910,7 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = "";
HEADER_SEARCH_PATHS = (
../macosx,
/opt/local/include,
.,
../posix,
@@ -17960,6 +17963,7 @@
GCC_MODEL_TUNING = G4;
GCC_PREPROCESSOR_DEFINITIONS = "";
HEADER_SEARCH_PATHS = (
../macosx,
/opt/local/include,
.,
../posix,


+ 12
- 2
macosx/coreaudio/JackCoreAudioAdapter.cpp View File

@@ -908,16 +908,26 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
}

// AUHAL
#ifdef MAC_OS_X_VERSION_10_5
ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
Component HALOutput = FindNextComponent(NULL, &cd);

err1 = OpenAComponent(HALOutput, &fAUHAL);
if (err1 != noErr) {
jack_error("Error calling OpenAComponent");
printError(err1);
goto error;
}

#else
AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd);
err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL);
if (err1 != noErr) {
jack_error("Error calling AudioComponentInstanceNew");
printError(err1);
goto error;
}
#endif
err1 = AudioUnitInitialize(fAUHAL);
if (err1 != noErr) {
jack_error("Cannot initialize AUHAL unit");


+ 69
- 56
macosx/coreaudio/JackCoreAudioDriver.cpp View File

@@ -258,17 +258,21 @@ static CFStringRef GetDeviceName(AudioDeviceID id)
return (err == noErr) ? UIname : NULL;
}

static void ParseChannelList(const string& list, vector<int>& result)
static void ParseChannelList(const string& list, vector<int>& result, int max_chan)
{
stringstream ss(list);
string token;
int chan;
int chan;
while (ss >> token) {
istringstream ins;
ins.str(token);
ins >> chan;
result.push_back(chan);
if (chan < 0 || chan >= max_chan) {
jack_error("Ignore incorrect channel mapping value = %d", chan);
} else {
result.push_back(chan);
}
}
}

@@ -1384,56 +1388,56 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
}

/*
Return the max possible input channels in in_nChannels and output channels in out_nChannels.
Return the max possible input channels in in_maxChannels and output channels in out_maxChannels.
*/
int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchannels, int& outchannels, int& in_nChannels, int& out_nChannels, bool strict)
int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchannels, int& outchannels, int& in_maxChannels, int& out_maxChannels, bool strict)
{
OSStatus err = noErr;

if (capturing) {
err = GetTotalChannels(fDeviceID, in_nChannels, true);
err = GetTotalChannels(fDeviceID, in_maxChannels, true);
if (err != noErr) {
jack_error("SetupChannels : cannot get input channel number");
printError(err);
return -1;
} else {
jack_log("JackCoreAudioDriver::SetupChannels : max input channels : %d", in_nChannels);
jack_log("JackCoreAudioDriver::SetupChannels : max input channels : %d", in_maxChannels);
}
}

if (playing) {
err = GetTotalChannels(fDeviceID, out_nChannels, false);
err = GetTotalChannels(fDeviceID, out_maxChannels, false);
if (err != noErr) {
jack_error("Cannot get output channel number");
printError(err);
return -1;
} else {
jack_log("JackCoreAudioDriver::SetupChannels : max output channels : %d", out_nChannels);
jack_log("JackCoreAudioDriver::SetupChannels : max output channels : %d", out_maxChannels);
}
}

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

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

if (inchannels == -1) {
jack_log("JackCoreAudioDriver::SetupChannels : setup max in channels = %d", in_nChannels);
inchannels = in_nChannels;
jack_log("JackCoreAudioDriver::SetupChannels : setup max in channels = %d", in_maxChannels);
inchannels = in_maxChannels;
}

if (outchannels == -1) {
jack_log("JackCoreAudioDriver::SetupChannels : setup max out channels = %d", out_nChannels);
outchannels = out_nChannels;
jack_log("JackCoreAudioDriver::SetupChannels : setup max out channels = %d", out_maxChannels);
outchannels = out_maxChannels;
}

return 0;
@@ -1509,7 +1513,6 @@ error:
// Remove BS change notification
AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyBufferFrameSize, BSNotificationCallback);
return -1;

}

int JackCoreAudioDriver::SetupSampleRate(jack_nframes_t sample_rate)
@@ -1594,8 +1597,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
bool playing,
int inchannels,
int outchannels,
int in_nChannels,
int out_nChannels,
int in_maxChannels,
int out_maxChannels,
const vector<int>& chan_in_list,
const vector<int>& chan_out_list,
jack_nframes_t buffer_size,
@@ -1607,24 +1610,34 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
AudioDeviceID currAudioDeviceID;
UInt32 size;

jack_log("JackCoreAudioDriver::OpenAUHAL : capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d chan_in_list = %d chan_out_list = %d",
capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, chan_in_list.size(), chan_out_list.size());
jack_log("JackCoreAudioDriver::OpenAUHAL : capturing = %d playing = %d inchannels = %d outchannels = %d in_maxChannels = %d out_maxChannels = %d chan_in_list = %d chan_out_list = %d",
capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, chan_in_list.size(), chan_out_list.size());

if (inchannels == 0 && outchannels == 0) {
jack_error("No input and output channels...");
return -1;
}
// AUHAL
#ifdef MAC_OS_X_VERSION_10_5
ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
Component HALOutput = FindNextComponent(NULL, &cd);

err1 = OpenAComponent(HALOutput, &fAUHAL);
if (err1 != noErr) {
jack_error("Error calling OpenAComponent");
printError(err1);
goto error;
}
#else
AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd);
err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL);
if (err1 != noErr) {
jack_error("Error calling AudioComponentInstanceNew");
printError(err1);
goto error;
}
#endif

err1 = AudioUnitInitialize(fAUHAL);
if (err1 != noErr) {
@@ -1702,16 +1715,16 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
}

// Setup input channel map
if (capturing && inchannels > 0 && inchannels <= in_nChannels) {
SInt32 chanArr[in_nChannels];
for (int i = 0; i < in_nChannels; i++) {
if (capturing && inchannels > 0 && inchannels <= in_maxChannels) {
SInt32 chanArr[in_maxChannels];
for (int i = 0; i < in_maxChannels; i++) {
chanArr[i] = -1;
}
// Explicit mapping
if (chan_in_list.size() > 0) {
for (uint i = 0; i < chan_in_list.size(); i++) {
int chan = chan_in_list[i];
if (chan < out_nChannels) {
if (chan < out_maxChannels) {
// The wanted JACK input index for the 'chan' channel value
chanArr[chan] = i;
jack_info("Input channel = %d ==> JACK input port = %d", chan, i);
@@ -1727,7 +1740,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
}
}

AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels);
AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_maxChannels);
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for input");
printError(err1);
@@ -1736,16 +1749,16 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
}

// Setup output channel map
if (playing && outchannels > 0 && outchannels <= out_nChannels) {
SInt32 chanArr[out_nChannels];
for (int i = 0; i < out_nChannels; i++) {
if (playing && outchannels > 0 && outchannels <= out_maxChannels) {
SInt32 chanArr[out_maxChannels];
for (int i = 0; i < out_maxChannels; i++) {
chanArr[i] = -1;
}
// Explicit mapping
if (chan_out_list.size() > 0) {
for (uint i = 0; i < chan_out_list.size(); i++) {
int chan = chan_out_list[i];
if (chan < out_nChannels) {
if (chan < out_maxChannels) {
// The wanted JACK output index for the 'chan' channel value
chanArr[chan] = i;
jack_info("JACK output port = %d ==> output channel = %d", i, chan);
@@ -1761,7 +1774,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
}
}

err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels);
err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_maxChannels);
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for output");
printError(err1);
@@ -1993,8 +2006,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
int ac3_bitrate,
bool ac3_lfe)
{
int in_nChannels = 0;
int out_nChannels = 0;
int in_maxChannels = 0;
int out_maxChannels = 0;
char capture_driver_name[256];
char playback_driver_name[256];

@@ -2012,19 +2025,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,

vector<int> parsed_chan_in_list;
vector<int> parsed_chan_out_list;

ParseChannelList(chan_in_list, parsed_chan_in_list);
if (parsed_chan_in_list.size() > 0) {
jack_info("Explicit input channel list size = %d", parsed_chan_in_list.size());
inchannels = parsed_chan_in_list.size();
}

ParseChannelList(chan_out_list, parsed_chan_out_list);
if (parsed_chan_out_list.size() > 0) {
jack_info("Explicit output channel list size = %d", parsed_chan_out_list.size());
outchannels = parsed_chan_out_list.size();
}

// Starting with 10.6 systems, the HAL notification thread is created internally
if (major == 10 && minor >= 6) {
CFRunLoopRef theRunLoop = NULL;
@@ -2052,9 +2053,21 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
goto error;
}

if (SetupChannels(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, !ac3_encoding) < 0) {
if (SetupChannels(capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, !ac3_encoding) < 0) {
goto error;
}
ParseChannelList(chan_in_list, parsed_chan_in_list, in_maxChannels);
if (parsed_chan_in_list.size() > 0) {
jack_info("Explicit input channel list size = %d", parsed_chan_in_list.size());
inchannels = parsed_chan_in_list.size();
}

ParseChannelList(chan_out_list, parsed_chan_out_list, out_maxChannels);
if (parsed_chan_out_list.size() > 0) {
jack_info("Explicit output channel list size = %d", parsed_chan_out_list.size());
outchannels = parsed_chan_out_list.size();
}

if (SetupBufferSize(buffer_size) < 0) {
goto error;
@@ -2096,7 +2109,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
}
// Force real output channel number to 2
outchannels = out_nChannels = 2;
outchannels = out_maxChannels = 2;
} else {
fPlaybackChannels = outchannels;
@@ -2105,7 +2118,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
// Core driver may have changed the in/out values
fCaptureChannels = inchannels;

if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, parsed_chan_in_list, parsed_chan_out_list, buffer_size, sample_rate) < 0) {
if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_maxChannels, out_maxChannels, parsed_chan_in_list, parsed_chan_out_list, buffer_size, sample_rate) < 0) {
goto error;
}

@@ -2455,8 +2468,8 @@ extern "C"
jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used");

value.str[0] = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "input-list", 'n', JackDriverParamString, &value, NULL, "Input channel list", "List of input channel number to be opened");
jack_driver_descriptor_add_parameter(desc, &filler, "output-list", 'N', JackDriverParamString, &value, NULL, "Output channel list", "List of output channel number to be opened");
jack_driver_descriptor_add_parameter(desc, &filler, "input-list", 'n', JackDriverParamString, &value, NULL, "Input channel list for channel mapping", "List of input channel number to be opened (syntax like : \"0 3 2\")");
jack_driver_descriptor_add_parameter(desc, &filler, "output-list", 'N', JackDriverParamString, &value, NULL, "Output channel list for channel mapping", "List of output channel number to be opened (syntax like : \"0 3 2\")");

value.str[0] = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input CoreAudio device name", NULL);
@@ -2650,7 +2663,7 @@ extern "C"
printf("Input channel list and in channels are both specified, input channel list will take over...\n");
}

if (strcmp(chan_out_list, "") != 0 && chan_out >= 0) {
if (strcmp(chan_out_list, "") != 0 && chan_out >= 0) {
printf("Output channel list and out channels are both specified, output channel list will take over...\n");
}



+ 2
- 1
macosx/coreaudio/TiPhoneCoreAudioRenderer.h View File

@@ -105,8 +105,9 @@ class TiPhoneCoreAudioRenderer
void PerformAudioCallback(int frames)
{
if (fAudioCallback)
if (fAudioCallback) {
fAudioCallback(frames, fInChannel, fOutChannel, fCallbackArg);
}
}

};


+ 6
- 5
macosx/coremidi/JackCoreMidiOutputPort.cpp View File

@@ -81,7 +81,11 @@ JackCoreMidiOutputPort::Execute()
packet = MIDIPacketListAdd(packet_list, PACKET_BUFFER_SIZE, packet,
timestamp, size, data);
if (packet) {
while (GetMicroSeconds() < send_time) {
do {
if (GetMicroSeconds() >= send_time) {
event = 0;
break;
}
event = GetCoreMidiEvent(false);
if (! event) {
break;
@@ -90,10 +94,7 @@ JackCoreMidiOutputPort::Execute()
packet,
GetTimeStampFromFrames(event->time),
event->size, event->buffer);
if (! packet) {
break;
}
}
} while (packet);
SendPacketList(packet_list);
} else {



+ 20
- 10
macosx/install_jackdmp View File

@@ -5,9 +5,9 @@
[ -d JackRouter.plugin ] && sudo cp -r JackRouter.plugin /Library/Audio/Plug-Ins/HAL/

# Copy libraries and exe
sudo cp -r Jackmp.framework /Library/Frameworks/
sudo cp -r Jackservermp.framework /Library/Frameworks/
sudo cp -r Jacknet.framework /Library/Frameworks/
sudo cp -r Jackmp.framework /System/Library/Frameworks/
sudo cp -r Jackservermp.framework /System/Library/Frameworks/
sudo cp -r Jacknet.framework /System/Library/Frameworks/
sudo install -d /usr/local/bin
sudo cp jackdmp /usr/local/bin
[ -f jack_load ] && sudo cp jack_load /usr/local/bin
@@ -29,16 +29,26 @@ sudo cp jack_loopback.so /usr/local/lib/jackmp
[ -f audioadapter.so ] && sudo cp audioadapter.so /usr/local/lib/jackmp

# Create links to jackmp ressources
cd /usr/local/lib && [ -f libjack.0.dylib ] && sudo mv -f libjack.0.dylib tmp_libjack.0.dylib
cd /usr/local/lib && [ -f jackd ] && sudo mv -f jackd tmp_jackd
cd /usr/local/bin && [ -f jackd ] && sudo rm jackd

cd /usr/local/lib && [ -f libjack.0.dylib ] && sudo rm libjack.0.dylib
cd /usr/local/lib && [ -f libjack.dylib ] && sudo rm libjack.dylib

cd /usr/local/lib && [ -f libjackserver.0.dylib ] && sudo rm libjackserver.0.dylib
cd /usr/local/lib && [ -f libjackserver.dylib ] && sudo rm libjackserver.dylib

cd /usr/local/lib && [ -f libjacknet.dylib ] && sudo rm libjacknet.dylib
cd /usr/local/lib && [ -f libjacknet.0.dylib ] && sudo rm libjacknet.0.dylib
cd /usr/local/bin && [ -f jackd ] && sudo rm jackd
cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jackmp.framework/Jackmp libjack.dylib
cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jackmp.framework/Jackmp libjack.0.dylib
cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jacknet.framework/Jacknet libjacknet.dylib
cd /usr/local/lib && sudo ln -s /Library/Frameworks/Jacknet.framework/Jacknet libjacknet.0.dylib

cd /usr/local/lib && sudo ln -s /System/Library/Frameworks/Jackmp.framework/Jackmp libjack.dylib
cd /usr/local/lib && sudo ln -s /System/Library/Frameworks/Jackmp.framework/Jackmp libjack.0.dylib

cd /usr/local/lib && sudo ln -s /System/Library/Frameworks/Jackservermp.framework/Jackservermp libjackserver.dylib
cd /usr/local/lib && sudo ln -s /System/Library/Frameworks/Jackservermp.framework/Jackservermp libjackserver.0.dylib

cd /usr/local/lib && sudo ln -s /System/Library/Frameworks/Jacknet.framework/Jacknet libjacknet.dylib
cd /usr/local/lib && sudo ln -s /System/Library/Frameworks/Jacknet.framework/Jacknet libjacknet.0.dylib

cd /usr/local/bin && sudo ln -s jackdmp jackd



+ 3
- 7
macosx/remove_jackdmp View File

@@ -3,14 +3,10 @@ sudo rm -r "/usr/local/lib/jackmp"
sudo rm "/usr/local/bin/jackdmp"
sudo rm -r "/usr/local/lib/jackd"
sudo rm "/usr/local/lib/libjackmp.dylib"
sudo rm -r "/Library/Frameworks/Jackmp.framework"
sudo rm -r "/Library/Frameworks/Jackservermp.framework"
sudo rm -r "/Library/Frameworks/Jacknet.framework"
sudo rm -r "/System/Library/Frameworks/Jackmp.framework"
sudo rm -r "/System/Library/Frameworks/Jackservermp.framework"
sudo rm -r "/System/Library/Frameworks/Jacknet.framework"
sudo rm -r "/Library/Audio/Plug-Ins/HAL/JackRouter.plugin"

# Tries to restore jack
cd /usr/local/lib && sudo rm -r libjack.0.dylib
cd /usr/local/lib && [ -f tmp_libjack.0.dylib ] && sudo mv -f tmp_libjack.0.dylib libjack.0.dylib
cd /usr/local/lib && ln -s libjack.0.dylib libjack.dylib
cd /usr/local/bin && [ -f tmp_jackd ] && sudo mv -f tmp_jackd jackd


+ 5
- 2
posix/JackPosixServerLaunch.cpp View File

@@ -73,7 +73,7 @@ static int start_server_dbus(const char* server_name)
return 0;
}

#else
#elif defined(USE_CLASSIC_AUTOLAUNCH)

/* Exec the JACK server in this process. Does not return. */
static void start_server_classic_aux(const char* server_name)
@@ -199,8 +199,11 @@ static int start_server(const char* server_name, jack_options_t options)

#if defined(USE_LIBDBUS_AUTOLAUNCH)
return start_server_dbus(server_name);
#else
#elif defined(USE_CLASSIC_AUTOLAUNCH)
return start_server_classic(server_name);
#else
fprintf(stderr, "Automatic start of JACK server is disabled at configure time\n");
return 1;
#endif
}



+ 1
- 1
posix/JackSocketServerChannel.cpp View File

@@ -97,7 +97,7 @@ int JackSocketServerChannel::Start()

void JackSocketServerChannel::Stop()
{
fThread.Kill();
fThread.Stop();
}

void JackSocketServerChannel::ClientCreate()


+ 1
- 1
solaris/wscript View File

@@ -6,7 +6,7 @@ def create_jack_driver_obj(bld, target, sources, uselib = None):
driver.features.append('cc')
driver.env['shlib_PATTERN'] = 'jack_%s.so'
#driver.env.append_unique('CXXFLAGS', '-march=i686 -msse3 -ffast-math')
#driver.env.append_unique('CCFLAGS', '-march=i686 -msse3 -ffast-math')
#driver.env.append_unique('CFLAGS', '-march=i686 -msse3 -ffast-math')
driver.defines = 'HAVE_CONFIG_H'
driver.includes = ['.', '..','../posix', '../common', '../common/jack']
driver.target = target


+ 100
- 88
tests/iodelay.cpp View File

@@ -1,6 +1,6 @@
/*
Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
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
@@ -24,135 +24,145 @@
#include <unistd.h>
#include <jack/jack.h>

class Freq
struct Freq
{
public:

int p;
int f;
float a;
float xa;
float ya;
float xf;
float yf;
float x1;
float y1;
float x2;
float y2;
};

class MTDM
{
public:

MTDM (void);
int process (size_t len, float *inp, float *out);
int resolve (void);
void invert (void) { _inv ^= 1; }
int inv (void) { return _inv; }
double del (void) { return _del; }
double err (void) { return _err; }


struct MTDM
{
double _del;
double _err;
float _wlp;
int _cnt;
int _inv;
Freq _freq [5];

struct Freq _freq [13];
};

MTDM::MTDM (void) : _cnt (0), _inv (0)

struct MTDM * mtdm_new (double fsamp)
{
int i;
Freq *F;

_freq [0].f = 4096;
_freq [1].f = 512;
_freq [2].f = 1088;
_freq [3].f = 1544;
_freq [4].f = 2049;

_freq [0].a = 0.2f;
_freq [1].a = 0.1f;
_freq [2].a = 0.1f;
_freq [3].a = 0.1f;
_freq [4].a = 0.1f;

for (i = 0, F = _freq; i < 5; i++, F++)
{
struct Freq *F;

struct MTDM *retval = (MTDM *)malloc( sizeof(struct MTDM) );

if (retval==NULL)
return NULL;

retval->_cnt = 0;
retval->_inv = 0;

retval->_freq [0].f = 4096;
retval->_freq [1].f = 2048;
retval->_freq [2].f = 3072;
retval->_freq [3].f = 2560;
retval->_freq [4].f = 2304;
retval->_freq [5].f = 2176;
retval->_freq [6].f = 1088;
retval->_freq [7].f = 1312;
retval->_freq [8].f = 1552;
retval->_freq [9].f = 1800;
retval->_freq [10].f = 3332;
retval->_freq [11].f = 3586;
retval->_freq [12].f = 3841;
retval->_wlp = 200.0f / fsamp;
for (i = 0, F = retval->_freq; i < 13; i++, F++) {
F->p = 128;
F->xa = F->ya = 0.0f;
F->xf = F->yf = 0.0f;
F->x1 = F->y1 = 0.0f;
F->x2 = F->y2 = 0.0f;
}

return retval;
}

int MTDM::process (size_t len, float *ip, float *op)
int mtdm_process (struct MTDM *self, size_t len, float *ip, float *op)
{
int i;
float vip, vop, a, c, s;
Freq *F;
struct Freq *F;

while (len--)
{
vop = 0.0f;
vip = *ip++;
for (i = 0, F = _freq; i < 5; i++, F++)
for (i = 0, F = self->_freq; i < 13; i++, F++)
{
a = 2 * (float) M_PI * (F->p & 65535) / 65536.0;
a = 2 * (float) M_PI * (F->p & 65535) / 65536.0;
F->p += F->f;
c = cosf (a);
s = -sinf (a);
vop += F->a * s;
c = cosf (a);
s = -sinf (a);
vop += (i ? 0.01f : 0.20f) * s;
F->xa += s * vip;
F->ya += c * vip;
}
}
*op++ = vop;
if (++_cnt == 16)
if (++self->_cnt == 16)
{
for (i = 0, F = _freq; i < 5; i++, F++)
for (i = 0, F = self->_freq; i < 13; i++, F++)
{
F->xf += 1e-3f * (F->xa - F->xf + 1e-20);
F->yf += 1e-3f * (F->ya - F->yf + 1e-20);
F->x1 += self->_wlp * (F->xa - F->x1 + 1e-20);
F->y1 += self->_wlp * (F->ya - F->y1 + 1e-20);
F->x2 += self->_wlp * (F->x1 - F->x2 + 1e-20);
F->y2 += self->_wlp * (F->y1 - F->y2 + 1e-20);
F->xa = F->ya = 0.0f;
}
_cnt = 0;
self->_cnt = 0;
}
}

return 0;
}

int MTDM::resolve (void)
int mtdm_resolve (struct MTDM *self)
{
int i, k, m;
double d, e, f0, p;
Freq *F = _freq;
struct Freq *F = self->_freq;

if (hypot (F->xf, F->yf) < 0.01) return -1;
d = atan2 (F->yf, F->xf) / (2 * M_PI);
if (_inv) d += 0.5f;
if (d > 0.5f) d -= 1.0f;
f0 = _freq [0].f;
if (hypot (F->x2, F->y2) < 0.001) return -1;
d = atan2 (F->y2, F->x2) / (2 * M_PI);
if (self->_inv) d += 0.5;
if (d > 0.5) d -= 1.0;
f0 = self->_freq [0].f;
m = 1;
_err = 0.0;
for (i = 0; i < 4; i++)
self->_err = 0.0;
for (i = 0; i < 12; i++)
{
F++;
p = atan2 (F->yf, F->xf) / (2 * M_PI) - d * F->f / f0;
if (_inv) p += 0.5f;
p = atan2 (F->y2, F->x2) / (2 * M_PI) - d * F->f / f0;
if (self->_inv) p += 0.5;
p -= floor (p);
p *= 8;
p *= 2;
k = (int)(floor (p + 0.5));
e = fabs (p - k);
if (e > _err) _err = e;
if (e > 0.4) return 1;
d += m * (k & 7);
m *= 8;
}
_del = 16 * d;
if (e > self->_err) self->_err = e;
if (e > 0.4) return 1;
d += m * (k & 1);
m *= 2;
}
self->_del = 16 * d;

return 0;
}

void mtdm_invert (struct MTDM *self)
{
self->_inv ^= 1;
}
// --------------------------------------------------------------------------------

static MTDM mtdm;
static struct MTDM *mtdm;
static jack_client_t *jack_handle;
static jack_port_t *jack_capt;
static jack_port_t *jack_play;
@@ -191,7 +201,7 @@ int jack_callback (jack_nframes_t nframes, void *arg)

ip = (float *)(jack_port_get_buffer (jack_capt, nframes));
op = (float *)(jack_port_get_buffer (jack_play, nframes));
mtdm.process (nframes, ip, op);
mtdm_process (mtdm, nframes, ip, op);
return 0;
}

@@ -207,6 +217,8 @@ int main (int ac, char *av [])
exit (1);
}

mtdm = mtdm_new(jack_get_sample_rate(jack_handle));

jack_set_process_callback (jack_handle, jack_callback, 0);

if (jack_set_latency_callback)
@@ -225,28 +237,28 @@ int main (int ac, char *av [])

while (1)
{
#ifdef WIN32
Sleep (250);
#else
usleep (250000);
#endif
if (mtdm.resolve() < 0) printf ("Signal below threshold...\n");
else
#ifdef WIN32
Sleep (250);
#else
usleep (250000);
#endif
if (mtdm_resolve (mtdm) < 0) printf ("Signal below threshold...\n");
else
{
jack_nframes_t systemic_latency;
if (mtdm.err () > 0.3)

if (mtdm->_err > 0.3)
{
mtdm.invert ();
mtdm.resolve ();
mtdm_invert ( mtdm );
mtdm_resolve ( mtdm );
}
systemic_latency = (jack_nframes_t) floor (mtdm._del - (capture_latency.max + playback_latency.max));
systemic_latency = (jack_nframes_t) floor (mtdm->_del - (capture_latency.max + playback_latency.max));

printf("%10.3lf frames %10.3lf ms total roundtrip latency\n\textra loopback latency: %u frames\n\tuse %u for the backend arguments -I and -O"
, mtdm._del, mtdm._del * t,
printf ("%10.3lf frames %10.3lf ms total roundtrip latency\n\textra loopback latency: %u frames\n\tuse %u for the backend arguments -I and -O", mtdm->_del, mtdm->_del * t,
systemic_latency, systemic_latency/2);
if (mtdm._err > 0.2) printf (" ??");
if (mtdm._inv) printf (" Inv");
if (mtdm->_err > 0.2) printf (" ??");
if (mtdm->_inv) printf (" Inv");
printf ("\n");
}
}
@@ -254,4 +266,4 @@ int main (int ac, char *av [])
return 0;
}

// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------

+ 1
- 1
windows/JackWinNamedPipeServerChannel.cpp View File

@@ -208,7 +208,7 @@ bool JackWinNamedPipeServerChannel::Init()

bool JackWinNamedPipeServerChannel::ClientListen()
{
if (fRequestListenPipe.Bind(jack_server_dir, fServerName, 0) < 0) {
if (fRequestListenPipe.Bind(jack_server_dir, fServerName, 0) < 0) {
jack_error("JackWinNamedPipeServerChannel::ClientListen : cannot create result listen pipe");
return false;
} else {


+ 0
- 3
windows/JackWinNamedPipeServerChannel.h View File

@@ -17,16 +17,13 @@

*/


#ifndef __JackWinNamedPipeServerChannel__
#define __JackWinNamedPipeServerChannel__

#include "JackWinNamedPipe.h"
#include "JackPlatformPlug.h"
#include "JackConstants.h"

#include "JackRequestDecoder.h"

#include <list>

namespace Jack


+ 4
- 4
windows/jackaudioadapter.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "audioadapter\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "audioadapter.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "audioadapter\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jackd.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_APP
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jack server for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "jackd\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "jackd.exe\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "jackd\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jackdummydriver.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp Dummy Driver for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "jack_dummy\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "jack_dummy.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "jack_dummy\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jackloopbackdriver.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp Loopback Driver for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "jack_loopback\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "jack_loopback.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "jack_loopback\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jacknetadapter.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp Net Adapter for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "netadapter\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "netadapter.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "netadapter\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jacknetdriver.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp Net Driver for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "jack_netdriver\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "jack_netdriver.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "jack_netdriver\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jacknetmanager.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp Net Manager for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "netmanager\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "netmanager.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "netmanager\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jacknetonedriver.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp NetOne Driver for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "jack_netonedriver\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "jack_netonedriver.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "jack_netonedriver\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jackportaudio.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "jack_portaudio\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "jack_portaudio.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "jack_portaudio\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/jackwinmme.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jackmp WinMME Driver for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "jack_portaudio\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "jack_winmme.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "jack_winmme\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/libjack.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jack client library for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "libjack\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "libjack.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "libjack\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/libjacknet.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jack Net library for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "libjacknet\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "libjacknet.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "libjacknet\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 4
- 4
windows/libjackserver.rc View File

@@ -11,8 +11,8 @@
//
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 1,9,9,3
PRODUCTVERSION 1,9,9,3
FILEVERSION 1,9,9,5
PRODUCTVERSION 1,9,9,5
FILEOS VOS_UNKNOWN
FILETYPE VFT_DLL
BEGIN
@@ -23,14 +23,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Grame\0"
VALUE "FileDescription", "Jack server library for Windows\0"
VALUE "FileVersion", "1, 9, 9, 3\0"
VALUE "FileVersion", "1, 9, 9, 5\0"
VALUE "InternalName", "libjackserver\0"
VALUE "LegalCopyright", "Copyright Grame © 2006-2012\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "libjackserver.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "libjackserver\0"
VALUE "ProductVersion", "1, 9, 9, 3\0"
VALUE "ProductVersion", "1, 9, 9, 5\0"
VALUE "SpecialBuild", "\0"
END
END


+ 56
- 31
windows/portaudio/JackPortAudioDevices.cpp View File

@@ -37,7 +37,7 @@ PortAudioDevices::PortAudioDevices()
}
fHostName = new string[fNumHostApi];
for (id = 0; id < fNumHostApi; id++) {
fHostName[id] = string (Pa_GetHostApiInfo(id)->name);
fHostName[id] = string(Pa_GetHostApiInfo(id)->name);
}
} else {
jack_error("JackPortAudioDriver::Pa_Initialize error = %s", Pa_GetErrorText(err));
@@ -97,7 +97,7 @@ string PortAudioDevices::GetFullName(std::string hostname, std::string devicenam
return (hostname + "::" + devicename);
}

PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName (string fullname, PaDeviceIndex& id, bool isInput)
PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName(string fullname, PaDeviceIndex& id, bool isInput)
{
PaDeviceInfo* ret = NULL;
//no driver to find
@@ -112,14 +112,14 @@ PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName (string fullname, PaDevice
}

char* hostname = (char*)malloc(separator + 9);
fill_n (hostname, separator + 9, 0);
fullname.copy (hostname, separator);
fill_n(hostname, separator + 9, 0);
fullname.copy(hostname, separator);

//we need the entire hostname, replace shortcuts
if (strcmp (hostname, "DirectSound") == 0) {
strcpy (hostname, "Windows DirectSound");
if (strcmp(hostname, "DirectSound") == 0) {
strcpy(hostname, "Windows DirectSound");
}
string devicename = fullname.substr (separator + 2);
string devicename = fullname.substr(separator + 2);
//then find the corresponding device
for (PaDeviceIndex dev_id = 0; dev_id < fNumDevice; dev_id++) {
bool flag = (isInput) ? (fDeviceInfo[dev_id]->maxInputChannels > 0) : (fDeviceInfo[dev_id]->maxOutputChannels > 0);
@@ -170,7 +170,7 @@ void PortAudioDevices::PrintSupportedStandardSampleRates(const PaStreamParameter
int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_input)
{
string fullname = string(devicename);
PaDeviceInfo* device = GetDeviceFromFullName (fullname, id, true);
PaDeviceInfo* device = GetDeviceFromFullName(fullname, id, true);
if (device) {
max_input = device->maxInputChannels;
} else {
@@ -189,7 +189,7 @@ int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceInd
int PortAudioDevices::GetOutputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_output)
{
string fullname = string(devicename);
PaDeviceInfo* device = GetDeviceFromFullName (fullname, id, false);
PaDeviceInfo* device = GetDeviceFromFullName(fullname, id, false);
if (device) {
max_output = device->maxOutputChannels;
} else {
@@ -205,54 +205,80 @@ int PortAudioDevices::GetOutputDeviceFromName(const char* devicename, PaDeviceIn
return id;
}

int PortAudioDevices::GetPreferredBufferSize(PaDeviceIndex id)
{
#ifdef WIN32
/* ASIO specific latency information */
if (Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO) {
long minLatency, maxLatency, preferredLatency, granularity;

PaAsio_GetAvailableBufferSizes(id, &minLatency, &maxLatency, &preferredLatency, &granularity);

jack_info("ASIO minimum buffer size = %ld", minLatency);
jack_info("ASIO maximum buffer size = %ld", maxLatency);
jack_info("ASIO preferred buffer size = %ld", preferredLatency);

if (granularity == -1) {
jack_info("ASIO buffer granularity = power of 2");
} else {
jack_info("ASIO buffer granularity = %ld", granularity);
}
return preferredLatency;
} else
#endif
{
return 512; // Non ASIO driver, returns generic value
}
}

void PortAudioDevices::DisplayDevicesNames()
{
PaDeviceIndex id;
PaStreamParameters inputParameters, outputParameters;
jack_info ("********************** Devices list, %d detected **********************", fNumDevice);
jack_info("********************** Devices list, %d detected **********************", fNumDevice);

for (id = 0; id < fNumDevice; id++) {
jack_info ("-------- device #%d ------------------------------------------------", id);
jack_info("-------- device #%d ------------------------------------------------", id);

if (id == Pa_GetDefaultInputDevice()) {
jack_info("[ Default Input ]");
} else if (id == Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi)->defaultInputDevice) {
const PaHostApiInfo *host_info = Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi);
} else if (id == Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->defaultInputDevice) {
const PaHostApiInfo *host_info = Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi);
jack_info("[ Default %s Input ]", host_info->name);
}

if (id == Pa_GetDefaultOutputDevice()) {
jack_info ("[ Default Output ]");
} else if (id == Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi)->defaultOutputDevice) {
const PaHostApiInfo *host_info = Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi);
jack_info("[ Default Output ]");
} else if (id == Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->defaultOutputDevice) {
const PaHostApiInfo *host_info = Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi);
jack_info("[ Default %s Output ]", host_info->name);
}

/* print device info fields */
jack_info ("Name = %s", GetFullName(id).c_str());
jack_info ("Max inputs = %d", fDeviceInfo[id]->maxInputChannels);
jack_info ("Max outputs = %d", fDeviceInfo[id]->maxOutputChannels);
#ifdef WIN32
jack_info("Name = %s", GetFullName(id).c_str());
jack_info("Max inputs = %d", fDeviceInfo[id]->maxInputChannels);
jack_info("Max outputs = %d", fDeviceInfo[id]->maxOutputChannels);
#ifdef WIN32
/* ASIO specific latency information */
if (Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO) {
long minLatency, maxLatency, preferredLatency, granularity;

PaAsio_GetAvailableBufferSizes (id, &minLatency, &maxLatency, &preferredLatency, &granularity);
PaAsio_GetAvailableBufferSizes(id, &minLatency, &maxLatency, &preferredLatency, &granularity);

jack_info ("ASIO minimum buffer size = %ld", minLatency);
jack_info ("ASIO maximum buffer size = %ld", maxLatency);
jack_info ("ASIO preferred buffer size = %ld", preferredLatency);
jack_info("ASIO minimum buffer size = %ld", minLatency);
jack_info("ASIO maximum buffer size = %ld", maxLatency);
jack_info("ASIO preferred buffer size = %ld", preferredLatency);

if (granularity == -1) {
jack_info ("ASIO buffer granularity = power of 2");
jack_info("ASIO buffer granularity = power of 2");
} else {
jack_info ("ASIO buffer granularity = %ld", granularity);
jack_info("ASIO buffer granularity = %ld", granularity);
}
}
#endif

jack_info ("Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate);
#endif
jack_info("Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate);

/* poll for standard sample rates */
inputParameters.device = id;
@@ -288,4 +314,3 @@ bool PortAudioDevices::IsDuplex(PaDeviceIndex id)
//then the device isn't full duplex
return false;
}


+ 1
- 0
windows/portaudio/JackPortAudioDevices.h View File

@@ -55,6 +55,7 @@ class PortAudioDevices
void PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters);
int GetInputDeviceFromName(const char* name, PaDeviceIndex& device, int& in_max);
int GetOutputDeviceFromName(const char* name, PaDeviceIndex& device, int& out_max);
int GetPreferredBufferSize(PaDeviceIndex id);
void DisplayDevicesNames();
bool IsDuplex(PaDeviceIndex id);



+ 27
- 26
windows/portaudio/JackPortAudioDriver.cpp View File

@@ -98,15 +98,15 @@ PaError JackPortAudioDriver::OpenStream(jack_nframes_t buffer_size)
inputParameters.channelCount = fCaptureChannels;
inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO
? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency
? ((fPaDevices->GetHostFromDevice(fInputDevice) == "ASIO") ? 0 : Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency)
: 0;
inputParameters.hostApiSpecificStreamInfo = NULL;

outputParameters.device = fOutputDevice;
outputParameters.channelCount = fPlaybackChannels;
outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO
? Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency
outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO
? ((fPaDevices->GetHostFromDevice(fOutputDevice) == "ASIO") ? 0 : Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency)
: 0;
outputParameters.hostApiSpecificStreamInfo = NULL;

@@ -167,17 +167,11 @@ int JackPortAudioDriver::Open(jack_nframes_t buffer_size,

fCaptureLatency = capture_latency;
fPlaybackLatency = playback_latency;
jack_log("JackPortAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s samplerate = %ld",
buffer_size, inchannels, outchannels, capture_driver_uid, playback_driver_uid, samplerate);

// Generic JackAudioDriver Open
if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor,
capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) {
return -1;
}

//get devices
// Get devices
if (capturing) {
if (fPaDevices->GetInputDeviceFromName(capture_driver_uid, fInputDevice, in_max) < 0) {
goto error;
@@ -188,10 +182,22 @@ int JackPortAudioDriver::Open(jack_nframes_t buffer_size,
goto error;
}
}
// If ASIO, request for preferred size (assuming fInputDevice and fOutputDevice are the same)
if (buffer_size == 0) {
buffer_size = fPaDevices->GetPreferredBufferSize(fInputDevice);
jack_log("JackPortAudioDriver::Open preferred buffer_size = %d", buffer_size);
}
// Generic JackAudioDriver Open
if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor,
capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) {
return -1;
}

jack_log("JackPortAudioDriver::Open fInputDevice = %d, fOutputDevice %d", fInputDevice, fOutputDevice);

//default channels number required
// Default channels number required
if (inchannels == 0) {
jack_log("JackPortAudioDriver::Open setup max in channels = %ld", in_max);
inchannels = in_max;
@@ -201,7 +207,7 @@ int JackPortAudioDriver::Open(jack_nframes_t buffer_size,
outchannels = out_max;
}

//too many channels required, take max available
// Too many channels required, take max available
if (inchannels > in_max) {
jack_error("This device has only %d available input channels.", in_max);
inchannels = in_max;
@@ -244,10 +250,9 @@ error:
int JackPortAudioDriver::Close()
{
// Generic audio driver close
int res = JackAudioDriver::Close();
jack_log("JackPortAudioDriver::Close");
Pa_CloseStream(fStream);
return res;
int res = JackAudioDriver::Close();
return (Pa_CloseStream(fStream) != paNoError) ? -1 : res;
}

int JackPortAudioDriver::Attach()
@@ -258,8 +263,7 @@ int JackPortAudioDriver::Attach()

if (fInputDevice != paNoDevice && fPaDevices->GetHostFromDevice(fInputDevice) == "ASIO") {
for (int i = 0; i < fCaptureChannels; i++) {
PaError err = PaAsio_GetInputChannelName(fInputDevice, i, &alias);
if (err == paNoError) {
if (PaAsio_GetInputChannelName(fInputDevice, i, &alias) == paNoError) {
JackPort* port = fGraphManager->GetPort(fCapturePortList[i]);
port->SetAlias(alias);
}
@@ -268,8 +272,7 @@ int JackPortAudioDriver::Attach()

if (fOutputDevice != paNoDevice && fPaDevices->GetHostFromDevice(fOutputDevice) == "ASIO") {
for (int i = 0; i < fPlaybackChannels; i++) {
PaError err = PaAsio_GetInputChannelName(fOutputDevice, i, &alias);
if (err == paNoError) {
if (PaAsio_GetOutputChannelName(fOutputDevice, i, &alias) == paNoError) {
JackPort* port = fGraphManager->GetPort(fPlaybackPortList[i]);
port->SetAlias(alias);
}
@@ -287,8 +290,7 @@ int JackPortAudioDriver::Start()
{
jack_log("JackPortAudioDriver::Start");
if (JackAudioDriver::Start() >= 0) {
PaError err = Pa_StartStream(fStream);
if (err == paNoError) {
if (Pa_StartStream(fStream) == paNoError) {
return 0;
}
JackAudioDriver::Stop();
@@ -299,8 +301,7 @@ int JackPortAudioDriver::Start()
int JackPortAudioDriver::Stop()
{
jack_log("JackPortAudioDriver::Stop");
PaError err = Pa_StopStream(fStream);
int res = (err == paNoError) ? 0 : -1;
int res = (Pa_StopStream(fStream) == paNoError) ? 0 : -1;
if (JackAudioDriver::Stop() < 0) {
res = -1;
}
@@ -362,7 +363,7 @@ extern "C"
jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);

value.ui = 512U;
jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);
jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", "Frames per period. If 0 and ASIO driver, will take preferred value");

jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "PortAudio device name", NULL);



+ 39
- 10
wscript View File

@@ -13,7 +13,7 @@ import re
import Logs
import sys

VERSION='1.9.9'
VERSION='1.9.9.5'
APPNAME='jack'
JACK_API_VERSION = '0.1.0'

@@ -76,6 +76,7 @@ def options(opt):
opt.add_option('--firewire', action='store_true', default=False, help='Enable FireWire driver (FFADO)')
opt.add_option('--freebob', action='store_true', default=False, help='Enable FreeBob driver')
opt.add_option('--alsa', action='store_true', default=False, help='Enable ALSA driver')
opt.add_option('--autostart', type='string', default="default", help='Autostart method. Possible values: "default", "classic", "dbus", "none"')
opt.sub_options('dbus')

def configure(conf):
@@ -116,7 +117,7 @@ def configure(conf):
# conf.check_tool('compiler_cc')
conf.env.append_unique('CXXFLAGS', '-Wall')
conf.env.append_unique('CCFLAGS', '-Wall')
conf.env.append_unique('CFLAGS', '-Wall')

conf.sub_config('common')
if conf.env['IS_LINUX']:
@@ -173,9 +174,18 @@ def configure(conf):
conf.define('HAVE_CELT_API_0_7', 0)
conf.define('HAVE_CELT_API_0_5', 0)

conf.env['WITH_OPUS'] = False
if conf.check_cfg(package='opus', atleast_version='0.9.0' , args='--cflags --libs', mandatory=False):
if conf.check_cc(header_name='opus/opus_custom.h', mandatory=False):
conf.define('HAVE_OPUS', 1)
conf.env['WITH_OPUS'] = True


conf.env['LIB_PTHREAD'] = ['pthread']
conf.env['LIB_DL'] = ['dl']
conf.env['LIB_RT'] = ['rt']
conf.env['LIB_M'] = ['m']
conf.env['LIB_STDC++'] = ['stdc++']
conf.env['JACK_API_VERSION'] = JACK_API_VERSION
conf.env['JACK_VERSION'] = VERSION

@@ -202,9 +212,30 @@ def configure(conf):

if conf.env['BUILD_DEBUG']:
conf.env.append_unique('CXXFLAGS', '-g')
conf.env.append_unique('CCFLAGS', '-g')
conf.env.append_unique('CFLAGS', '-g')
conf.env.append_unique('LINKFLAGS', '-g')

if not Options.options.autostart in ["default", "classic", "dbus", "none"]:
conf.fatal("Invalid autostart value \"" + Options.options.autostart + "\"")

if Options.options.autostart == "default":
if conf.env['BUILD_JACKDBUS'] == True and conf.env['BUILD_JACKD'] == False:
conf.env['AUTOSTART_METHOD'] = "dbus"
else:
conf.env['AUTOSTART_METHOD'] = "classic"
else:
conf.env['AUTOSTART_METHOD'] = Options.options.autostart

if conf.env['AUTOSTART_METHOD'] == "dbus" and not conf.env['BUILD_JACKDBUS']:
conf.fatal("D-Bus autostart mode was specified but jackdbus will not be built")
if conf.env['AUTOSTART_METHOD'] == "classic" and not conf.env['BUILD_JACKD']:
conf.fatal("Classic autostart mode was specified but jackd will not be built")

if conf.env['AUTOSTART_METHOD'] == "dbus":
conf.define('USE_LIBDBUS_AUTOLAUNCH', 1)
elif conf.env['AUTOSTART_METHOD'] == "classic":
conf.define('USE_CLASSIC_AUTOLAUNCH', 1)

conf.define('CLIENT_NUM', Options.options.clients)
conf.define('PORT_NUM_FOR_CLIENT', Options.options.application_ports)

@@ -215,11 +246,9 @@ def configure(conf):
conf.define('JACKMP', 1)
if conf.env['BUILD_JACKDBUS'] == True:
conf.define('JACK_DBUS', 1)
if conf.env['BUILD_JACKD'] == False:
conf.define('USE_LIBDBUS_AUTOLAUNCH', 1)
if conf.env['BUILD_WITH_PROFILE'] == True:
conf.define('JACK_MONITOR', 1)
conf.write_config_header('config.h')
conf.write_config_header('config.h', remove=False)

svnrev = None
if os.access('svnversion.h', os.R_OK):
@@ -228,15 +257,13 @@ def configure(conf):
if m != None:
svnrev = m.group(1)

conf.env.append_unique('LINKFLAGS', ['-lm', '-lstdc++'])

if Options.options.mixed == True:
env_variant2 = conf.env.copy()
conf.set_env_name('lib32', env_variant2)
env_variant2.set_variant('lib32')
conf.setenv('lib32')
conf.env.append_unique('CXXFLAGS', '-m32')
conf.env.append_unique('CCFLAGS', '-m32')
conf.env.append_unique('CFLAGS', '-m32')
conf.env.append_unique('LINKFLAGS', '-m32')
if Options.options.libdir32:
conf.env['LIBDIR'] = Options.options.libdir32
@@ -260,15 +287,17 @@ def configure(conf):
display_msg("Library directory", conf.env['LIBDIR'], 'CYAN')
display_msg("Drivers directory", conf.env['ADDON_DIR'], 'CYAN')
display_feature('Build debuggable binaries', conf.env['BUILD_DEBUG'])
display_msg('C compiler flags', repr(conf.env['CCFLAGS']))
display_msg('C compiler flags', repr(conf.env['CFLAGS']))
display_msg('C++ compiler flags', repr(conf.env['CXXFLAGS']))
display_msg('Linker flags', repr(conf.env['LINKFLAGS']))
display_feature('Build doxygen documentation', conf.env['BUILD_DOXYGEN_DOCS'])
display_feature('Build Opus netjack2', conf.env['WITH_OPUS'])
display_feature('Build with engine profiling', conf.env['BUILD_WITH_PROFILE'])
display_feature('Build with 32/64 bits mixed mode', conf.env['BUILD_WITH_32_64'])

display_feature('Build standard JACK (jackd)', conf.env['BUILD_JACKD'])
display_feature('Build D-Bus JACK (jackdbus)', conf.env['BUILD_JACKDBUS'])
display_msg('Autostart method', conf.env['AUTOSTART_METHOD'])

if conf.env['BUILD_JACKDBUS'] and conf.env['BUILD_JACKD']:
print(Logs.colors.RED + 'WARNING !! mixing both jackd and jackdbus may cause issues:' + Logs.colors.NORMAL)


Loading…
Cancel
Save