| @@ -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 $<" | |||
| @@ -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; | |||
| @@ -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), | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -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]; | |||
| @@ -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; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -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*) | |||
| { | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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() | |||