From 4353ddd78da7b912e5f9de664ca89f6c82b03056 Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Wed, 2 Oct 2024 11:29:01 +0100 Subject: [PATCH] Add live shifter to C API --- rubberband/RubberBandLiveShifter.h | 2 +- rubberband/rubberband-c.h | 64 +++++++++++++++++++++---- src/rubberband-c.cpp | 76 ++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 9 deletions(-) diff --git a/rubberband/RubberBandLiveShifter.h b/rubberband/RubberBandLiveShifter.h index dbc23d6..1222adb 100644 --- a/rubberband/RubberBandLiveShifter.h +++ b/rubberband/RubberBandLiveShifter.h @@ -102,7 +102,7 @@ public: OptionFormantPreserved = 0x01000000, OptionChannelsApart = 0x00000000, - OptionChannelsTogether = 0x10000000, + OptionChannelsTogether = 0x10000000 // n.b. Options is int, so we must stop before 0x80000000 }; diff --git a/rubberband/rubberband-c.h b/rubberband/rubberband-c.h index 66d584b..b24bd78 100644 --- a/rubberband/rubberband-c.h +++ b/rubberband/rubberband-c.h @@ -48,11 +48,13 @@ extern "C" { * This is a C-linkage interface to the Rubber Band time stretcher. * * This is a wrapper interface: the primary interface is in C++ and is - * defined and documented in RubberBandStretcher.h. The library - * itself is implemented in C++, and requires C++ standard library - * support even when using the C-linkage API. + * defined and documented in RubberBandStretcher.h and + * RubberBandLiveShifter.h. The library itself is implemented in C++, + * and requires C++ standard library support even when using the + * C-linkage API. * - * Please see RubberBandStretcher.h for documentation. + * Please see RubberBandStretcher.h and RubberBandLiveShifter.h for + * documentation. * * If you are writing to the C++ API, do not include this header. */ @@ -107,10 +109,10 @@ struct RubberBandState_; typedef struct RubberBandState_ *RubberBandState; RB_EXTERN RubberBandState rubberband_new(unsigned int sampleRate, - unsigned int channels, - RubberBandOptions options, - double initialTimeRatio, - double initialPitchScale); + unsigned int channels, + RubberBandOptions options, + double initialTimeRatio, + double initialPitchScale); RB_EXTERN void rubberband_delete(RubberBandState); @@ -159,6 +161,52 @@ RB_EXTERN void rubberband_calculate_stretch(RubberBandState); RB_EXTERN void rubberband_set_debug_level(RubberBandState, int level); RB_EXTERN void rubberband_set_default_debug_level(int level); + +enum RubberBandLiveOption { + + RubberBandLiveOptionWindowShort = 0x00000000, + RubberBandLiveOptionWindowMedium = 0x00100000, + + RubberBandLiveOptionFormantShifted = 0x00000000, + RubberBandLiveOptionFormantPreserved = 0x01000000, + + RubberBandLiveOptionChannelsApart = 0x00000000, + RubberBandLiveOptionChannelsTogether = 0x10000000 +}; + +typedef int RubberBandLiveOptions; + +struct RubberBandLiveState_; +typedef struct RubberBandLiveState_ *RubberBandLiveState; + +RB_EXTERN RubberBandLiveState rubberband_live_new(unsigned int sampleRate, + unsigned int channels, + RubberBandOptions options); + +RB_EXTERN void rubberband_live_delete(RubberBandLiveState); + +RB_EXTERN void rubberband_live_reset(RubberBandLiveState); + +RB_EXTERN void rubberband_live_set_pitch_scale(RubberBandLiveState, double scale); +RB_EXTERN double rubberband_live_get_pitch_scale(const RubberBandLiveState); + +RB_EXTERN void rubberband_live_set_formant_scale(RubberBandLiveState, double scale); +RB_EXTERN double rubberband_live_get_formant_scale(const RubberBandLiveState); + +RB_EXTERN unsigned int rubberband_live_get_start_delay(const RubberBandLiveState); + +RB_EXTERN void rubberband_live_set_formant_option(RubberBandLiveState, RubberBandOptions options); + +RB_EXTERN unsigned int rubberband_live_get_block_size(RubberBandLiveState, RubberBandOptions options); + +RB_EXTERN void rubberband_live_shift(RubberBandLiveState, const float *const *input, float *const *output); + +RB_EXTERN unsigned int rubberband_live_get_channel_count(const RubberBandLiveState); + +RB_EXTERN void rubberband_live_set_debug_level(RubberBandLiveState, int level); +RB_EXTERN void rubberband_live_set_default_debug_level(int level); + + #ifdef __cplusplus } #endif diff --git a/src/rubberband-c.cpp b/src/rubberband-c.cpp index 7c450b0..9289c6c 100644 --- a/src/rubberband-c.cpp +++ b/src/rubberband-c.cpp @@ -23,6 +23,7 @@ #include "../rubberband/rubberband-c.h" #include "../rubberband/RubberBandStretcher.h" +#include "../rubberband/RubberBandLiveShifter.h" struct RubberBandState_ { @@ -197,3 +198,78 @@ void rubberband_set_default_debug_level(int level) RubberBand::RubberBandStretcher::setDefaultDebugLevel(level); } +struct RubberBandLiveState_ +{ + RubberBand::RubberBandLiveShifter *m_s; +}; + +RubberBandLiveState rubberband_live_new(unsigned int sampleRate, + unsigned int channels, + RubberBandOptions options) +{ + RubberBandLiveState_ *state = new RubberBandLiveState_(); + state->m_s = new RubberBand::RubberBandLiveShifter + (sampleRate, channels, options); + return state; +} + +void rubberband_live_delete(RubberBandLiveState state) +{ + delete state->m_s; + delete state; +} + +void rubberband_live_reset(RubberBandLiveState state) +{ + state->m_s->reset(); +} + +void rubberband_live_set_pitch_scale(RubberBandLiveState state, double scale) +{ + state->m_s->setPitchScale(scale); +} + +double rubberband_live_get_pitch_scale(const RubberBandLiveState state) +{ + return state->m_s->getPitchScale(); +} + +void rubberband_live_set_formant_scale(RubberBandLiveState state, double scale) +{ + state->m_s->setFormantScale(scale); +} + +double rubberband_live_get_formant_scale(const RubberBandLiveState state) +{ + return state->m_s->getFormantScale(); +} + +unsigned int rubberband_live_get_start_delay(const RubberBandLiveState state) +{ + return (unsigned int)state->m_s->getStartDelay(); +} + +void rubberband_live_set_formant_option(RubberBandLiveState state, RubberBandOptions options) +{ + state->m_s->setFormantOption(options); +} + +void rubberband_live_shift(RubberBandLiveState state, const float *const *input, float *const *output) +{ + state->m_s->shift(input, output); +} + +unsigned int rubberband_live_get_channel_count(const RubberBandLiveState state) +{ + return (unsigned int)state->m_s->getChannelCount(); +} + +void rubberband_live_set_debug_level(RubberBandLiveState state, int level) +{ + state->m_s->setDebugLevel(level); +} + +void rubberband_live_set_default_debug_level(int level) +{ + RubberBand::RubberBandStretcher::setDefaultDebugLevel(level); +}