Browse Source

More libjack work (ringbuffer and dummy metadata, uuid and stats)

tags/1.9.8
falkTX 7 years ago
parent
commit
c3a2135f29
10 changed files with 681 additions and 107 deletions
  1. +9
    -1
      source/libjack/Makefile
  2. +70
    -66
      source/libjack/libjack.cpp
  3. +5
    -0
      source/libjack/libjack.hpp
  4. +8
    -2
      source/libjack/libjack_callbacks.cpp
  5. +120
    -30
      source/libjack/libjack_metadata.cpp
  6. +2
    -2
      source/libjack/libjack_port-searching.cpp
  7. +10
    -3
      source/libjack/libjack_ports.cpp
  8. +41
    -0
      source/libjack/libjack_stats.cpp
  9. +405
    -0
      source/libjack/ringbuffer.c
  10. +11
    -3
      source/tests/carla-plugin-jack.py

+ 9
- 1
source/libjack/Makefile View File

@@ -21,6 +21,7 @@ endif

# ----------------------------------------------------------------------------------------------------------------------

BUILD_C_FLAGS += -I$(CWD) -I$(CWD)/includes
BUILD_CXX_FLAGS += -I$(CWD) -I$(CWD)/backend -I$(CWD)/includes -I$(CWD)/modules -I$(CWD)/utils
LINK_FLAGS += $(MODULEDIR)/juce_core.a
LINK_FLAGS += $(JUCE_CORE_LIBS)
@@ -44,8 +45,10 @@ OBJS = \
$(OBJDIR)/libjack_ports.cpp.o \
$(OBJDIR)/libjack_port-searching.cpp.o \
$(OBJDIR)/libjack_server-control.cpp.o \
$(OBJDIR)/libjack_stats.cpp.o \
$(OBJDIR)/libjack_time.cpp.o \
$(OBJDIR)/libjack_transport.cpp.o
$(OBJDIR)/libjack_transport.cpp.o \
$(OBJDIR)/ringbuffer.c.o
TARGET = $(BINDIR)/jack/libjack.so.0
endif

@@ -70,6 +73,11 @@ $(TARGET): $(OBJS)

# ----------------------------------------------------------------------------------------------------------------------

$(OBJDIR)/%.c.o: %.c
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
@$(CC) $< $(BUILD_C_FLAGS) -c -o $@

$(OBJDIR)/%.cpp.o: %.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"


+ 70
- 66
source/libjack/libjack.cpp View File

@@ -551,88 +551,88 @@ void CarlaJackAppClient::run()

if (cmtl.wasLocked())
{
// tranport for all clients
const BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);

fServer.playing = bridgeTimeInfo.playing;
fServer.position.frame = bridgeTimeInfo.frame;
fServer.position.usecs = bridgeTimeInfo.usecs;

if (bridgeTimeInfo.valid & 0x1 /* kValidBBT */)
{
fServer.position.valid = JackPositionBBT;

fServer.position.bar = bridgeTimeInfo.bar;
fServer.position.beat = bridgeTimeInfo.beat;
fServer.position.tick = bridgeTimeInfo.tick;

fServer.position.beats_per_bar = bridgeTimeInfo.beatsPerBar;
fServer.position.beat_type = bridgeTimeInfo.beatType;

fServer.position.ticks_per_beat = bridgeTimeInfo.ticksPerBeat;
fServer.position.beats_per_minute = bridgeTimeInfo.beatsPerMinute;
fServer.position.bar_start_tick = bridgeTimeInfo.barStartTick;
}
else
{
fServer.position.valid = static_cast<jack_position_bits_t>(0);
}

float* fdata = fShmAudioPool.data;

if (JackClientState* const jclient = fClients.getFirst(nullptr))
//for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
if (! fClients.isEmpty())
{
//JackClientState* const jclient(it.getValue(nullptr));
//CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
// tranport for all clients
const BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);

const CarlaMutexTryLocker cmtl2(jclient->mutex);
fServer.playing = bridgeTimeInfo.playing;
fServer.position.frame = bridgeTimeInfo.frame;
fServer.position.usecs = bridgeTimeInfo.usecs;

if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated)
if (bridgeTimeInfo.valid & 0x1 /* kValidBBT */)
{
if (fAudioIns > 0)
fdata += fServer.bufferSize*fAudioIns;
fServer.position.valid = JackPositionBBT;

if (fAudioOuts > 0)
carla_zeroFloats(fdata, fServer.bufferSize*fAudioOuts);
fServer.position.bar = bridgeTimeInfo.bar;
fServer.position.beat = bridgeTimeInfo.beat;
fServer.position.tick = bridgeTimeInfo.tick;

if (jclient->deactivated)
{
fShmRtClientControl.data->procFlags = 1;
}
fServer.position.beats_per_bar = bridgeTimeInfo.beatsPerBar;
fServer.position.beat_type = bridgeTimeInfo.beatType;

fServer.position.ticks_per_beat = bridgeTimeInfo.ticksPerBeat;
fServer.position.beats_per_minute = bridgeTimeInfo.beatsPerMinute;
fServer.position.bar_start_tick = bridgeTimeInfo.barStartTick;
}
else
{
uint32_t i;
fServer.position.valid = static_cast<jack_position_bits_t>(0);
}

i = 0;
for (LinkedList<JackPortState*>::Itenerator it = jclient->audioIns.begin2(); it.valid(); it.next())
{
CARLA_SAFE_ASSERT_BREAK(i++ < fAudioIns);
if (JackPortState* const jport = it.getValue(nullptr))
jport->buffer = fdata;
fdata += fServer.bufferSize;
}
for (; i++ < fAudioIns;)
fdata += fServer.bufferSize;
for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
{
JackClientState* const jclient(it.getValue(nullptr));
CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);

const CarlaMutexTryLocker cmtl2(jclient->mutex);

i = 0;
for (LinkedList<JackPortState*>::Itenerator it = jclient->audioOuts.begin2(); it.valid(); it.next())
if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated)
{
CARLA_SAFE_ASSERT_BREAK(i++ < fAudioOuts);
if (JackPortState* const jport = it.getValue(nullptr))
jport->buffer = fdata;
fdata += fServer.bufferSize;
if (fAudioIns > 0)
fdata += fServer.bufferSize*fAudioIns;

if (fAudioOuts > 0)
carla_zeroFloats(fdata, fServer.bufferSize*fAudioOuts);

if (jclient->deactivated)
{
fShmRtClientControl.data->procFlags = 1;
}
}
for (; i++ < fAudioOuts;)
else
{
//carla_stderr("clearing buffer %i", i);

carla_zeroFloats(fdata, fServer.bufferSize);
fdata += fServer.bufferSize;
uint32_t i;

i = 0;
for (LinkedList<JackPortState*>::Itenerator it = jclient->audioIns.begin2(); it.valid(); it.next())
{
CARLA_SAFE_ASSERT_BREAK(i++ < fAudioIns);
if (JackPortState* const jport = it.getValue(nullptr))
jport->buffer = fdata;
fdata += fServer.bufferSize;
}
for (; i++ < fAudioIns;)
fdata += fServer.bufferSize;

i = 0;
for (LinkedList<JackPortState*>::Itenerator it = jclient->audioOuts.begin2(); it.valid(); it.next())
{
CARLA_SAFE_ASSERT_BREAK(i++ < fAudioOuts);
if (JackPortState* const jport = it.getValue(nullptr))
jport->buffer = fdata;
fdata += fServer.bufferSize;
}
for (; i++ < fAudioOuts;)
{
carla_zeroFloats(fdata, fServer.bufferSize);
fdata += fServer.bufferSize;
}

jclient->processCb(fServer.bufferSize, jclient->processCbPtr);
}

jclient->processCb(fServer.bufferSize, jclient->processCbPtr);
}
}
else
@@ -679,7 +679,11 @@ void CarlaJackAppClient::run()
{
const CarlaMutexLocker cms(fRealtimeThreadMutex);

if (JackClientState* const jclient = fClients.getLast(nullptr))
if (fClients.isEmpty())
{
activated = false;
}
else if (JackClientState* const jclient = fClients.getLast(nullptr))
{
const CarlaMutexLocker cms(jclient->mutex);
activated = jclient->activated;


+ 5
- 0
source/libjack/libjack.hpp View File

@@ -120,6 +120,9 @@ struct JackClientState {
JackProcessCallback processCb;
void* processCbPtr;

JackFreewheelCallback freewheelCb;
void* freewheelCbPtr;

JackBufferSizeCallback bufferSizeCb;
void* bufferSizeCbPtr;

@@ -144,6 +147,8 @@ struct JackClientState {
infoShutdownCbPtr(nullptr),
processCb(nullptr),
processCbPtr(nullptr),
freewheelCb(nullptr),
freewheelCbPtr(nullptr),
bufferSizeCb(nullptr),
bufferSizeCbPtr(nullptr),
sampleRateCb(nullptr),


+ 8
- 2
source/libjack/libjack_callbacks.cpp View File

@@ -15,7 +15,6 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

// need to include this first
#include "libjack.hpp"

CARLA_BACKEND_USE_NAMESPACE
@@ -66,8 +65,15 @@ int jack_set_process_callback(jack_client_t* client, JackProcessCallback callbac
}

CARLA_EXPORT
int jack_set_freewheel_callback(jack_client_t*, JackFreewheelCallback, void*)
int jack_set_freewheel_callback(jack_client_t* client, JackFreewheelCallback callback, void* arg)
{
JackClientState* const jclient = (JackClientState*)client;
CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);

const CarlaMutexLocker cms(jclient->mutex);

jclient->freewheelCb = callback;
jclient->freewheelCbPtr = arg;
return 0;
}



+ 120
- 30
source/libjack/libjack_metadata.cpp View File

@@ -15,9 +15,12 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

// need to include this first
#include "libjack.hpp"

#define JACK_UUID_SIZE 36
#define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */
#define JACK_UUID_EMPTY_INITIALIZER 0

CARLA_BACKEND_USE_NAMESPACE

// --------------------------------------------------------------------------------------------------------------------
@@ -26,45 +29,132 @@ CARLA_EXPORT
const char* JACK_METADATA_PRETTY_NAME;
const char* JACK_METADATA_PRETTY_NAME = "http://jackaudio.org/metadata/pretty-name";

// extern const char* JACK_METADATA_HARDWARE;
// extern const char* JACK_METADATA_CONNECTED;
// extern const char* JACK_METADATA_PORT_GROUP;
// extern const char* JACK_METADATA_ICON_SMALL;
// extern const char* JACK_METADATA_ICON_LARGE;
CARLA_EXPORT
const char* JACK_METADATA_HARDWARE;
const char* JACK_METADATA_HARDWARE = "http://jackaudio.org/metadata/hardware";

CARLA_EXPORT
const char* JACK_METADATA_CONNECTED;
const char* JACK_METADATA_CONNECTED = "http://jackaudio.org/metadata/connected";

CARLA_EXPORT
const char* JACK_METADATA_PORT_GROUP;
const char* JACK_METADATA_PORT_GROUP = "http://jackaudio.org/metadata/port-group";

CARLA_EXPORT
const char* JACK_METADATA_ICON_SMALL;
const char* JACK_METADATA_ICON_SMALL = "http://jackaudio.org/metadata/icon-small";

CARLA_EXPORT
const char* JACK_METADATA_ICON_LARGE;
const char* JACK_METADATA_ICON_LARGE = "http://jackaudio.org/metadata/icon-large";

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

// int
// jack_set_property(jack_client_t*,
// jack_uuid_t subject,
// const char* key,
// const char* value,
// const char* type);
CARLA_EXPORT
int jack_set_property(jack_client_t*, jack_uuid_t, const char*, const char*, const char*)
{
return -1;
}

// int
// jack_get_property(jack_uuid_t subject,
// const char* key,
// char** value,
// char** type);
CARLA_EXPORT
int jack_get_property(jack_uuid_t, const char*, char**, char**)
{
return -1;
}

// void
// jack_free_description (jack_description_t* desc, int free_description_itself);
CARLA_EXPORT
void jack_free_description(jack_description_t*, int)
{
}

CARLA_EXPORT
int jack_get_properties(jack_uuid_t, jack_description_t*)
{
return -1;
}

// int
// jack_get_properties (jack_uuid_t subject,
// jack_description_t* desc);
CARLA_EXPORT
int jack_get_all_properties(jack_description_t**)
{
return -1;
}

// int
// jack_get_all_properties (jack_description_t** descs);
CARLA_EXPORT
int jack_remove_property(jack_client_t*, jack_uuid_t, const char*)
{
return -1;
}

// int jack_remove_property (jack_client_t* client, jack_uuid_t subject, const char* key);
CARLA_EXPORT
int jack_remove_properties(jack_client_t*, jack_uuid_t)
{
return -1;
}

// int jack_remove_properties (jack_client_t* client, jack_uuid_t subject);
CARLA_EXPORT
int jack_remove_all_properties(jack_client_t*)
{
return -1;
}

// int jack_remove_all_properties (jack_client_t* client);
CARLA_EXPORT
int jack_set_property_change_callback(jack_client_t*, JackPropertyChangeCallback, void*)
{
return -1;
}

// int jack_set_property_change_callback (jack_client_t* client,
// JackPropertyChangeCallback callback,
// void* arg);
// --------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT
jack_uuid_t jack_client_uuid_generate()
{
return 0;
}

CARLA_EXPORT
jack_uuid_t jack_port_uuid_generate(uint32_t)
{
return 0;
}

CARLA_EXPORT
uint32_t jack_uuid_to_index(jack_uuid_t)
{
return 0;
}

CARLA_EXPORT
int jack_uuid_compare(jack_uuid_t, jack_uuid_t)
{
return 0;
}

CARLA_EXPORT
void jack_uuid_copy(jack_uuid_t*, jack_uuid_t)
{
}

CARLA_EXPORT
void jack_uuid_clear(jack_uuid_t*)
{
}

CARLA_EXPORT
int jack_uuid_parse(const char*, jack_uuid_t*)
{
return 0;
}

CARLA_EXPORT
void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE])
{
}

CARLA_EXPORT
int jack_uuid_empty(jack_uuid_t)
{
return 0;
}

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

+ 2
- 2
source/libjack/libjack_port-searching.cpp View File

@@ -98,7 +98,7 @@ jack_port_t* jack_port_by_name(jack_client_t* /*client*/, const char* name)
{
name += 8;

const int index = std::atoi(name);
const int index = std::atoi(name)-1;
CARLA_SAFE_ASSERT_RETURN(index >= 0 && index < 2, nullptr);

return (jack_port_t*)&capturePorts[index];
@@ -107,7 +107,7 @@ jack_port_t* jack_port_by_name(jack_client_t* /*client*/, const char* name)
{
name += 9;

const int index = std::atoi(name);
const int index = std::atoi(name)-1;
CARLA_SAFE_ASSERT_RETURN(index >= 0, nullptr);

return (jack_port_t*)&playbackPorts[index];


+ 10
- 3
source/libjack/libjack_ports.cpp View File

@@ -175,10 +175,17 @@ int jack_port_connected(const jack_port_t*)

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

// const char ** jack_port_get_connections (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT;
CARLA_EXPORT
const char** jack_port_get_connections (const jack_port_t*)
{
return nullptr;
}

// const char ** jack_port_get_all_connections (const jack_client_t *client,
// const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT;
CARLA_EXPORT
const char** jack_port_get_all_connections(const jack_client_t*, const jack_port_t*)
{
return nullptr;
}

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



+ 41
- 0
source/libjack/libjack_stats.cpp View File

@@ -0,0 +1,41 @@
/*
* Carla JACK API for external applications
* Copyright (C) 2016-2017 Filipe Coelho <falktx@falktx.com>
*
* 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 any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "libjack.hpp"

CARLA_BACKEND_USE_NAMESPACE

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

CARLA_EXPORT
float jack_get_max_delayed_usecs(jack_client_t*)
{
return 0.0f;
}

CARLA_EXPORT
float jack_get_xrun_delayed_usecs(jack_client_t*)
{
return 0.0f;
}

CARLA_EXPORT
void jack_reset_max_delayed_usecs(jack_client_t*)
{
}

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

+ 405
- 0
source/libjack/ringbuffer.c View File

@@ -0,0 +1,405 @@
/*
Copyright (C) 2000 Paul Davis
Copyright (C) 2003 Rohan Drape

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.

ISO/POSIX C version of Paul Davis's lock free ringbuffer C++ code.
This is safe for the case of one read thread and one write thread.
*/

#include <stdlib.h>
#include <string.h>
#ifdef USE_MLOCK
#include <sys/mman.h>
#endif /* USE_MLOCK */
#include "CarlaDefines.h"

typedef struct {
char *buf;
size_t len;
}
jack_ringbuffer_data_t ;

typedef struct {
char *buf;
volatile size_t write_ptr;
volatile size_t read_ptr;
size_t size;
size_t size_mask;
int mlocked;
}
jack_ringbuffer_t ;

CARLA_EXPORT jack_ringbuffer_t *jack_ringbuffer_create(size_t sz);
CARLA_EXPORT void jack_ringbuffer_free(jack_ringbuffer_t *rb);
CARLA_EXPORT void jack_ringbuffer_get_read_vector(const jack_ringbuffer_t *rb,
jack_ringbuffer_data_t *vec);
CARLA_EXPORT void jack_ringbuffer_get_write_vector(const jack_ringbuffer_t *rb,
jack_ringbuffer_data_t *vec);
CARLA_EXPORT size_t jack_ringbuffer_read(jack_ringbuffer_t *rb, char *dest, size_t cnt);
CARLA_EXPORT size_t jack_ringbuffer_peek(jack_ringbuffer_t *rb, char *dest, size_t cnt);
CARLA_EXPORT void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt);
CARLA_EXPORT size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb);
CARLA_EXPORT int jack_ringbuffer_mlock(jack_ringbuffer_t *rb);
CARLA_EXPORT void jack_ringbuffer_reset(jack_ringbuffer_t *rb);
CARLA_EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz);
CARLA_EXPORT size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src,
size_t cnt);
void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt);
size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb);

/* Create a new ringbuffer to hold at least `sz' bytes of data. The
actual buffer size is rounded up to the next power of two. */

CARLA_EXPORT jack_ringbuffer_t *
jack_ringbuffer_create (size_t sz)
{
int power_of_two;
jack_ringbuffer_t *rb;

if ((rb = (jack_ringbuffer_t *) malloc (sizeof (jack_ringbuffer_t))) == NULL) {
return NULL;
}

for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++);

rb->size = 1 << power_of_two;
rb->size_mask = rb->size;
rb->size_mask -= 1;
rb->write_ptr = 0;
rb->read_ptr = 0;
if ((rb->buf = (char *) malloc (rb->size)) == NULL) {
free (rb);
return NULL;
}
rb->mlocked = 0;

return rb;
}

/* Free all data associated with the ringbuffer `rb'. */

CARLA_EXPORT void
jack_ringbuffer_free (jack_ringbuffer_t * rb)
{
#ifdef USE_MLOCK
if (rb->mlocked) {
munlock (rb->buf, rb->size);
}
#endif /* USE_MLOCK */
free (rb->buf);
free (rb);
}

/* Lock the data block of `rb' using the system call 'mlock'. */

CARLA_EXPORT int
jack_ringbuffer_mlock (jack_ringbuffer_t * rb)
{
#ifdef USE_MLOCK
if (mlock (rb->buf, rb->size)) {
return -1;
}
#endif /* USE_MLOCK */
rb->mlocked = 1;
return 0;
}

/* Reset the read and write pointers to zero. This is not thread
safe. */

CARLA_EXPORT void
jack_ringbuffer_reset (jack_ringbuffer_t * rb)
{
rb->read_ptr = 0;
rb->write_ptr = 0;
memset(rb->buf, 0, rb->size);
}

/* Reset the read and write pointers to zero. This is not thread
safe. */

CARLA_EXPORT void
jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz)
{
rb->size = sz;
rb->size_mask = rb->size;
rb->size_mask -= 1;
rb->read_ptr = 0;
rb->write_ptr = 0;
}

/* Return the number of bytes available for reading. This is the
number of bytes in front of the read pointer and behind the write
pointer. */

CARLA_EXPORT size_t
jack_ringbuffer_read_space (const jack_ringbuffer_t * rb)
{
size_t w, r;

w = rb->write_ptr;
r = rb->read_ptr;

if (w > r) {
return w - r;
} else {
return (w - r + rb->size) & rb->size_mask;
}
}

/* Return the number of bytes available for writing. This is the
number of bytes in front of the write pointer and behind the read
pointer. */

CARLA_EXPORT size_t
jack_ringbuffer_write_space (const jack_ringbuffer_t * rb)
{
size_t w, r;

w = rb->write_ptr;
r = rb->read_ptr;

if (w > r) {
return ((r - w + rb->size) & rb->size_mask) - 1;
} else if (w < r) {
return (r - w) - 1;
} else {
return rb->size - 1;
}
}

/* The copying data reader. Copy at most `cnt' bytes from `rb' to
`dest'. Returns the actual number of bytes copied. */

CARLA_EXPORT size_t
jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt)
{
size_t free_cnt;
size_t cnt2;
size_t to_read;
size_t n1, n2;

if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) {
return 0;
}

to_read = cnt > free_cnt ? free_cnt : cnt;

cnt2 = rb->read_ptr + to_read;

if (cnt2 > rb->size) {
n1 = rb->size - rb->read_ptr;
n2 = cnt2 & rb->size_mask;
} else {
n1 = to_read;
n2 = 0;
}

memcpy (dest, &(rb->buf[rb->read_ptr]), n1);
rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask;

if (n2) {
memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2);
rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask;
}

return to_read;
}

/* The copying data reader w/o read pointer advance. Copy at most
`cnt' bytes from `rb' to `dest'. Returns the actual number of bytes
copied. */

CARLA_EXPORT size_t
jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt)
{
size_t free_cnt;
size_t cnt2;
size_t to_read;
size_t n1, n2;
size_t tmp_read_ptr;

tmp_read_ptr = rb->read_ptr;

if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) {
return 0;
}

to_read = cnt > free_cnt ? free_cnt : cnt;

cnt2 = tmp_read_ptr + to_read;

if (cnt2 > rb->size) {
n1 = rb->size - tmp_read_ptr;
n2 = cnt2 & rb->size_mask;
} else {
n1 = to_read;
n2 = 0;
}

memcpy (dest, &(rb->buf[tmp_read_ptr]), n1);
tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask;

if (n2) {
memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2);
}

return to_read;
}

/* The copying data writer. Copy at most `cnt' bytes to `rb' from
`src'. Returns the actual number of bytes copied. */

CARLA_EXPORT size_t
jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt)
{
size_t free_cnt;
size_t cnt2;
size_t to_write;
size_t n1, n2;

if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) {
return 0;
}

to_write = cnt > free_cnt ? free_cnt : cnt;

cnt2 = rb->write_ptr + to_write;

if (cnt2 > rb->size) {
n1 = rb->size - rb->write_ptr;
n2 = cnt2 & rb->size_mask;
} else {
n1 = to_write;
n2 = 0;
}

memcpy (&(rb->buf[rb->write_ptr]), src, n1);
rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask;

if (n2) {
memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2);
rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask;
}

return to_write;
}

/* Advance the read pointer `cnt' places. */

CARLA_EXPORT void
jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt)
{
size_t tmp = (rb->read_ptr + cnt) & rb->size_mask;
rb->read_ptr = tmp;
}

/* Advance the write pointer `cnt' places. */

CARLA_EXPORT void
jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt)
{
size_t tmp = (rb->write_ptr + cnt) & rb->size_mask;
rb->write_ptr = tmp;
}

/* The non-copying data reader. `vec' is an array of two places. Set
the values at `vec' to hold the current readable data at `rb'. If
the readable data is in one segment the second segment has zero
length. */

CARLA_EXPORT void
jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb,
jack_ringbuffer_data_t * vec)
{
size_t free_cnt;
size_t cnt2;
size_t w, r;

w = rb->write_ptr;
r = rb->read_ptr;

if (w > r) {
free_cnt = w - r;
} else {
free_cnt = (w - r + rb->size) & rb->size_mask;
}

cnt2 = r + free_cnt;

if (cnt2 > rb->size) {

/* Two part vector: the rest of the buffer after the current write
ptr, plus some from the start of the buffer. */

vec[0].buf = &(rb->buf[r]);
vec[0].len = rb->size - r;
vec[1].buf = rb->buf;
vec[1].len = cnt2 & rb->size_mask;

} else {

/* Single part vector: just the rest of the buffer */

vec[0].buf = &(rb->buf[r]);
vec[0].len = free_cnt;
vec[1].len = 0;
}
}

/* The non-copying data writer. `vec' is an array of two places. Set
the values at `vec' to hold the current writeable data at `rb'. If
the writeable data is in one segment the second segment has zero
length. */

CARLA_EXPORT void
jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb,
jack_ringbuffer_data_t * vec)
{
size_t free_cnt;
size_t cnt2;
size_t w, r;

w = rb->write_ptr;
r = rb->read_ptr;

if (w > r) {
free_cnt = ((r - w + rb->size) & rb->size_mask) - 1;
} else if (w < r) {
free_cnt = (r - w) - 1;
} else {
free_cnt = rb->size - 1;
}

cnt2 = w + free_cnt;

if (cnt2 > rb->size) {

/* Two part vector: the rest of the buffer after the current write
ptr, plus some from the start of the buffer. */

vec[0].buf = &(rb->buf[w]);
vec[0].len = rb->size - w;
vec[1].buf = rb->buf;
vec[1].len = cnt2 & rb->size_mask;
} else {
vec[0].buf = &(rb->buf[w]);
vec[0].len = free_cnt;
vec[1].len = 0;
}
}


+ 11
- 3
source/tests/carla-plugin-jack.py View File

@@ -24,17 +24,25 @@ def signalHandler(sig, frame):

# --------------------------------------------------------------------------------------------------------

binaryDir = "/home/falktx/Personal/FOSS/GIT/falkTX/Carla/bin"
host = CarlaHostDLL("/home/falktx/FOSS/GIT-mine/falkTX/Carla/bin/libcarla_standalone2.so", True)
binaryDir = "/home/falktx/Personal/GIT-mine/falkTX/Carla/bin"
host = CarlaHostDLL("/home/falktx/Personal/GIT-mine/falkTX/Carla/bin/libcarla_standalone2.so", True)
host.set_engine_option(ENGINE_OPTION_PATH_BINARIES, 0, binaryDir)
host.set_engine_option(ENGINE_OPTION_PROCESS_MODE, 2, "")
host.set_engine_option(ENGINE_OPTION_TRANSPORT_MODE, 0, "")

if not host.engine_init("JACK", "Carla-Plugin-JACK"):
if not host.engine_init("PulseAudio", "Carla-Plugin-JACK"):
print("Engine failed to initialize, possible reasons:\n%s" % host.get_last_error())
exit(1)

fname = "/usr/bin/pulseaudio"
label = "--high-priority --realtime --exit-idle-time=-1 --file=/usr/share/cadence/pulse2jack/play.pa -n"

fname = "/usr/bin/patchage"
label = ""

fname = "/usr/bin/carla"
label = ""

if not host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, fname, "", label, 0, None, 0):
print("Failed to load plugin, possible reasons:\n%s" % host.get_last_error())
host.engine_close()


Loading…
Cancel
Save