From b727e5e2bdd2a12ed89e9e56fbc0622ae01516b1 Mon Sep 17 00:00:00 2001 From: Laxmi Devi Date: Thu, 11 Jul 2019 10:06:29 +0530 Subject: [PATCH] JackAPI: Export interface form Jack to support S32 and S16 Applications can now call jack_port_create_converter() to create an instance of the object ForwardJackPortConverter for float and S32JackPortConverter for int32_t and int16_t And then they can use the Get() and Set() of the object to get and set the pointers to the memory area associated with the specified port. Change-Id: I4a5a0c627941b263cdc5e1e7bbdab920a9b9e4f6 Signed-off-by: Laxmi Devi Signed-off-by: Timo Wischer --- common/JackFormatConverter.cpp | 115 +++++++++++++++++++++++++++++++++ common/jack/format_converter.h | 62 ++++++++++++++++++ common/wscript | 2 + 3 files changed, 179 insertions(+) create mode 100644 common/JackFormatConverter.cpp create mode 100644 common/jack/format_converter.h diff --git a/common/JackFormatConverter.cpp b/common/JackFormatConverter.cpp new file mode 100644 index 00000000..2f5f5138 --- /dev/null +++ b/common/JackFormatConverter.cpp @@ -0,0 +1,115 @@ +/* + Copyright (C) 2019 Laxmi Devi + Copyright (C) 2019 Timo Wischer + + + 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. + +*/ + +#include +#include +#include +#include "JackCompilerDeps.h" +#include "JackError.h" +#include "memops.h" + + +class BaseJackPortConverter : public IJackPortConverter { + protected: + jack_port_t* const port; + public: + BaseJackPortConverter(jack_port_t* pt) : port(pt) {} +}; + +class ForwardJackPortConverter : public BaseJackPortConverter { + private: + void* buffer = NULL; + public: + ForwardJackPortConverter(jack_port_t* pt) : BaseJackPortConverter(pt) {} + + virtual void* get( jack_nframes_t frames) { + buffer = jack_port_get_buffer(port, frames); + return buffer; + } + + virtual void set(void* buf, jack_nframes_t frames) { + if (buf == buffer) + return; + std::memcpy(jack_port_get_buffer(port, frames), buf, frames*sizeof(jack_default_audio_sample_t)); + } +}; + +class IntegerJackPortConverter : public BaseJackPortConverter { + typedef void (*ReadCopyFunction) (jack_default_audio_sample_t *dst, char *src, + unsigned long src_bytes, + unsigned long src_skip_bytes); + typedef void (*WriteCopyFunction) (char *dst, jack_default_audio_sample_t *src, + unsigned long src_bytes, + unsigned long dst_skip_bytes, + dither_state_t *state); + + private: + int32_t buffer[BUFFER_SIZE_MAX + 8]; + const ReadCopyFunction to_jack; + const WriteCopyFunction from_jack; + const size_t sample_size; + + int32_t* GetBuffer() + { + return (int32_t*)((uintptr_t)buffer & ~31L) + 8; + } + + public: + IntegerJackPortConverter(const ReadCopyFunction to_jack, + const WriteCopyFunction from_jack, + const size_t sample_size, + jack_port_t* pt) : BaseJackPortConverter(pt), + to_jack(to_jack), from_jack(from_jack), sample_size(sample_size) {} + + virtual void* get(jack_nframes_t frames) { + int32_t * aligned_ptr = GetBuffer(); + jack_default_audio_sample_t* src = (jack_default_audio_sample_t*) jack_port_get_buffer(port, frames); + from_jack ((char *)aligned_ptr, src, frames, sample_size, NULL); + return aligned_ptr; + } + + virtual void set(void* src, jack_nframes_t frames) { + jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*) jack_port_get_buffer(port, frames); + to_jack (dst,(char *) src, frames, sample_size); + return; + } +}; + +LIB_EXPORT IJackPortConverter* jack_port_create_converter(jack_port_t* port, const std::type_info& dst_type, const bool init_output_silence) +{ + if(dst_type == (typeid(jack_default_audio_sample_t))) { + return new ForwardJackPortConverter(port); + } + else if(dst_type == (typeid(int32_t))) { + return new IntegerJackPortConverter(sample_move_dS_s32, + sample_move_d32_sS, sizeof(int32_t), + port); + } + else if(dst_type == (typeid(int16_t))) { + return new IntegerJackPortConverter(sample_move_dS_s16, + sample_move_d16_sS, sizeof(int16_t), + port); + } + else { + jack_error("jack_port_create_converter called with dst_type that is not supported"); + return NULL; + } +} diff --git a/common/jack/format_converter.h b/common/jack/format_converter.h new file mode 100644 index 00000000..0fc8907f --- /dev/null +++ b/common/jack/format_converter.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2019 Laxmi Devi + Copyright (C) 2019 Timo Wischer + + + 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_format_converter_h__ +#define __jack_format_converter_h__ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + + +class IJackPortConverter { + + public: + + virtual void* get(jack_nframes_t frames) = 0; + virtual void set(void* buf, jack_nframes_t frames) = 0; +}; + +/** + * This returns a pointer to the instance of the object IJackPortConverter based + * on the dst_type. Applications can use the get() and set() + * of this object to get and set the pointers to the memory area associated with the specified port. + * Currently Jack only supports Float, int32_t and int16_t. + * + * @param port jack_port_t pointer. + * @param dst_type type required by client. + * @param init_output_silence if true, jack will initialize the output port with silence + * + * @return ptr to IJackPortConverter on success, otherwise NULL if dst_type is not supported. + */ + +IJackPortConverter* jack_port_create_converter(jack_port_t* port, const std::type_info& dst_type, const bool init_output_silence=true) JACK_OPTIONAL_WEAK_EXPORT; + +#ifdef __cplusplus +} +#endif + +#endif // __jack_format_converter_h__ diff --git a/common/wscript b/common/wscript index 4dc5f9ed..ecf99563 100755 --- a/common/wscript +++ b/common/wscript @@ -69,6 +69,8 @@ def build(bld): 'JackTools.cpp', 'JackMessageBuffer.cpp', 'JackEngineProfiling.cpp', + 'memops.c', + 'JackFormatConverter.cpp' ] includes = ['.', './jack']