diff --git a/source/libjack/Makefile b/source/libjack/Makefile index d3c3a3557..13da478cd 100644 --- a/source/libjack/Makefile +++ b/source/libjack/Makefile @@ -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 $<" diff --git a/source/libjack/libjack.cpp b/source/libjack/libjack.cpp index fb4cfd113..6b4c45c6b 100644 --- a/source/libjack/libjack.cpp +++ b/source/libjack/libjack.cpp @@ -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(0); - } - float* fdata = fShmAudioPool.data; - if (JackClientState* const jclient = fClients.getFirst(nullptr)) - //for (LinkedList::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(0); + } - i = 0; - for (LinkedList::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::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::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::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::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; diff --git a/source/libjack/libjack.hpp b/source/libjack/libjack.hpp index baf2f1fdb..9180501eb 100644 --- a/source/libjack/libjack.hpp +++ b/source/libjack/libjack.hpp @@ -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), diff --git a/source/libjack/libjack_callbacks.cpp b/source/libjack/libjack_callbacks.cpp index 3f3872e91..85fc20d0e 100644 --- a/source/libjack/libjack_callbacks.cpp +++ b/source/libjack/libjack_callbacks.cpp @@ -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; } diff --git a/source/libjack/libjack_metadata.cpp b/source/libjack/libjack_metadata.cpp index b108d311d..b950a2892 100644 --- a/source/libjack/libjack_metadata.cpp +++ b/source/libjack/libjack_metadata.cpp @@ -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; +} // -------------------------------------------------------------------------------------------------------------------- diff --git a/source/libjack/libjack_port-searching.cpp b/source/libjack/libjack_port-searching.cpp index c2383ffde..65d80158d 100644 --- a/source/libjack/libjack_port-searching.cpp +++ b/source/libjack/libjack_port-searching.cpp @@ -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]; diff --git a/source/libjack/libjack_ports.cpp b/source/libjack/libjack_ports.cpp index 021460f18..e029579c1 100644 --- a/source/libjack/libjack_ports.cpp +++ b/source/libjack/libjack_ports.cpp @@ -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; +} // -------------------------------------------------------------------------------------------------------------------- diff --git a/source/libjack/libjack_stats.cpp b/source/libjack/libjack_stats.cpp new file mode 100644 index 000000000..2b815c884 --- /dev/null +++ b/source/libjack/libjack_stats.cpp @@ -0,0 +1,41 @@ +/* + * Carla JACK API for external applications + * Copyright (C) 2016-2017 Filipe Coelho + * + * 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*) +{ +} + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/libjack/ringbuffer.c b/source/libjack/ringbuffer.c new file mode 100644 index 000000000..a6ea7b5de --- /dev/null +++ b/source/libjack/ringbuffer.c @@ -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 +#include +#ifdef USE_MLOCK +#include +#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; + } +} + diff --git a/source/tests/carla-plugin-jack.py b/source/tests/carla-plugin-jack.py index 503fa751f..c534f678e 100755 --- a/source/tests/carla-plugin-jack.py +++ b/source/tests/carla-plugin-jack.py @@ -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()