diff --git a/.hgtags b/.hgtags index 759bc726..68c6b99b 100644 --- a/.hgtags +++ b/.hgtags @@ -36,3 +36,4 @@ b7f4072d02d551ba39e11d95fdeb5478f371076c v3.1.1 d2aebfc83e21e7ce597cdb59029eb8500e53c24c v3.1.2 46d8430844d6454ed140d4e8631372a6c65e856a v3.2.0 83d096887e1b9042f9e4a8f1b975d18539e82f22 v3.2.1 +55367f2e76c9ee79582c8bebdd63b14c98e459be v3.3.0 diff --git a/CHANGELOG b/CHANGELOG index a1a7aeb1..3ffa0699 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,17 @@ +Changes in Rubber Band v3.3 + +This is a bug-fix release with no changes to audio quality. + + * Fix incorrect output with unexpectedly large buffers in process + * Add getProcessSizeLimit to query the maximum buffer length for + process and highest supported value for setMaxProcessSize + * Fix formal test failure in some contexts + +One new function has been added to the API. The library is otherwise +binary compatible with existing code back to version 1.7. + + Changes in Rubber Band v3.2.1 This is a build-fix release with no new features. diff --git a/Doxyfile b/Doxyfile index a8a7e9fe..f084e33d 100644 --- a/Doxyfile +++ b/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = "Rubber Band Library" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 3.2.1 +PROJECT_NUMBER = 3.3.0 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -414,7 +414,7 @@ GENERATE_BUGLIST = YES # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. -GENERATE_DEPRECATEDLIST= YES +GENERATE_DEPRECATEDLIST= NO # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. diff --git a/ladspa-lv2/rubberband.lv2/lv2-rubberband.ttl b/ladspa-lv2/rubberband.lv2/lv2-rubberband.ttl index 0621e10f..eff06d20 100644 --- a/ladspa-lv2/rubberband.lv2/lv2-rubberband.ttl +++ b/ladspa-lv2/rubberband.lv2/lv2-rubberband.ttl @@ -135,7 +135,7 @@ rubberband:mono doap:maintainer :maker ; # Minor version will be 2x the Rubber Band API minor version lv2:minorVersion 4 ; - lv2:microVersion 1 ; + lv2:microVersion 2 ; lv2:optionalFeature lv2:hardRTCapable ; pg:mainInput rubberband:mono_in_group ; pg:mainOutput rubberband:mono_out_group ; @@ -173,7 +173,7 @@ rubberband:r3mono doap:maintainer :maker ; # Minor version will be 2x the Rubber Band API minor version lv2:minorVersion 4 ; - lv2:microVersion 1 ; + lv2:microVersion 2 ; lv2:optionalFeature lv2:hardRTCapable ; pg:mainInput rubberband:mono_in_group ; pg:mainOutput rubberband:mono_out_group ; @@ -247,7 +247,7 @@ rubberband:stereo doap:maintainer :maker ; # Minor version will be 2x the Rubber Band API minor version lv2:minorVersion 4 ; - lv2:microVersion 1 ; + lv2:microVersion 2 ; lv2:optionalFeature lv2:hardRTCapable ; pg:mainInput rubberband:stereo_in_group ; pg:mainOutput rubberband:stereo_out_group ; @@ -300,7 +300,7 @@ rubberband:r3stereo doap:maintainer :maker ; # Minor version will be 2x the Rubber Band API minor version lv2:minorVersion 4 ; - lv2:microVersion 1 ; + lv2:microVersion 2 ; lv2:optionalFeature lv2:hardRTCapable ; pg:mainInput rubberband:stereo_in_group ; pg:mainOutput rubberband:stereo_out_group ; diff --git a/meson.build b/meson.build index c21f0d3c..050dbd56 100644 --- a/meson.build +++ b/meson.build @@ -2,7 +2,7 @@ project( 'Rubber Band Library', 'c', 'cpp', - version: '3.2.1', + version: '3.3.0', license: 'GPL-2.0-or-later', default_options: [ 'cpp_std=c++11', @@ -15,7 +15,7 @@ project( meson_version: '>= 0.53.0' ) -rubberband_dynamic_library_version = '2.2.4' +rubberband_dynamic_library_version = '2.3.0' system = host_machine.system() architecture = host_machine.cpu_family() diff --git a/rubberband/RubberBandStretcher.h b/rubberband/RubberBandStretcher.h index 2227bee0..6b883a87 100644 --- a/rubberband/RubberBandStretcher.h +++ b/rubberband/RubberBandStretcher.h @@ -24,9 +24,9 @@ #ifndef RUBBERBAND_STRETCHER_H #define RUBBERBAND_STRETCHER_H -#define RUBBERBAND_VERSION "3.2.1" +#define RUBBERBAND_VERSION "3.3.0" #define RUBBERBAND_API_MAJOR_VERSION 2 -#define RUBBERBAND_API_MINOR_VERSION 7 +#define RUBBERBAND_API_MINOR_VERSION 8 #undef RUBBERBAND_DLLEXPORT #ifdef _MSC_VER @@ -805,10 +805,10 @@ RubberBandStretcher * * Despite the existence of this call and its use of a size_t * argument, there is an internal limit to the maximum process - * buffer size that can be requested. This is currently 524288 (or - * 2^19). The Rubber Band API is essentially block-based and is - * not designed to process an entire signal within a single - * process cycle. + * buffer size that can be requested. Call getProcessSizeLimit() + * to query that limit. The Rubber Band API is essentially + * block-based and is not designed to process an entire signal + * within a single process cycle. * * Note that the value of "samples" refers to the number of audio * sample frames, which may be multi-channel, not the number of @@ -818,6 +818,18 @@ RubberBandStretcher */ void setMaxProcessSize(size_t samples); + /** + * Obtain the overall maximum supported process buffer size in + * sample frames, which is also the maximum acceptable value to + * pass to setMaxProcessSize(). This value is fixed across + * instances and configurations. As of Rubber Band v3.3 it is + * always 524288 (or 2^19), but in principle it may change in + * future releases. + * + * This function was added in Rubber Band Library v3.3. + */ + size_t getProcessSizeLimit() const; + /** * Ask the stretcher how many audio sample frames should be * provided as input in order to ensure that some more output diff --git a/rubberband/rubberband-c.h b/rubberband/rubberband-c.h index 0788c6b3..73d1216b 100644 --- a/rubberband/rubberband-c.h +++ b/rubberband/rubberband-c.h @@ -29,9 +29,9 @@ extern "C" { #endif -#define RUBBERBAND_VERSION "3.2.1" +#define RUBBERBAND_VERSION "3.3.0" #define RUBBERBAND_API_MAJOR_VERSION 2 -#define RUBBERBAND_API_MINOR_VERSION 7 +#define RUBBERBAND_API_MINOR_VERSION 8 #undef RB_EXTERN #ifdef _MSC_VER @@ -138,6 +138,8 @@ RB_EXTERN void rubberband_set_expected_input_duration(RubberBandState, unsigned RB_EXTERN unsigned int rubberband_get_samples_required(const RubberBandState); RB_EXTERN void rubberband_set_max_process_size(RubberBandState, unsigned int samples); +RB_EXTERN unsigned int rubberband_get_process_size_limit(RubberBandState); + RB_EXTERN void rubberband_set_key_frame_map(RubberBandState, unsigned int keyframecount, unsigned int *from, unsigned int *to); RB_EXTERN void rubberband_study(RubberBandState, const float *const *input, unsigned int samples, int final); diff --git a/src/RubberBandStretcher.cpp b/src/RubberBandStretcher.cpp index a5e373fa..930fd41a 100644 --- a/src/RubberBandStretcher.cpp +++ b/src/RubberBandStretcher.cpp @@ -226,6 +226,13 @@ class RubberBandStretcher::Impl else m_r3->setMaxProcessSize(samples); } + size_t + getProcessSizeLimit() const + { + if (m_r2) return m_r2->getProcessSizeLimit(); + else return m_r3->getProcessSizeLimit(); + } + void setKeyFrameMap(const std::map &mapping) { @@ -492,6 +499,12 @@ RubberBandStretcher::setMaxProcessSize(size_t samples) m_d->setMaxProcessSize(samples); } +size_t +RubberBandStretcher::getProcessSizeLimit() const +{ + return m_d->getProcessSizeLimit(); +} + void RubberBandStretcher::setKeyFrameMap(const std::map &mapping) { diff --git a/src/faster/R2Stretcher.cpp b/src/faster/R2Stretcher.cpp index 1ad1eecb..13b09565 100644 --- a/src/faster/R2Stretcher.cpp +++ b/src/faster/R2Stretcher.cpp @@ -316,6 +316,12 @@ R2Stretcher::setMaxProcessSize(size_t samples) reconfigure(); } +size_t +R2Stretcher::getProcessSizeLimit() const +{ + return 524288; +} + void R2Stretcher::setKeyFrameMap(const std::map &mapping) { diff --git a/src/faster/R2Stretcher.h b/src/faster/R2Stretcher.h index 3bda6f51..ea3ddab7 100644 --- a/src/faster/R2Stretcher.h +++ b/src/faster/R2Stretcher.h @@ -73,6 +73,7 @@ class R2Stretcher void setExpectedInputDuration(size_t samples); void setMaxProcessSize(size_t samples); + size_t getProcessSizeLimit() const; void setKeyFrameMap(const std::map &); size_t getSamplesRequired() const; diff --git a/src/finer/R3Stretcher.cpp b/src/finer/R3Stretcher.cpp index 32fb8c12..ea1b2c83 100644 --- a/src/finer/R3Stretcher.cpp +++ b/src/finer/R3Stretcher.cpp @@ -652,6 +652,12 @@ R3Stretcher::setMaxProcessSize(size_t requested) ensureOutbuf(n * 8, false); } +size_t +R3Stretcher::getProcessSizeLimit() const +{ + return m_limits.overallMaxProcessSize; +} + void R3Stretcher::ensureInbuf(int required, bool warn) { diff --git a/src/finer/R3Stretcher.h b/src/finer/R3Stretcher.h index cea37423..5f9e5608 100644 --- a/src/finer/R3Stretcher.h +++ b/src/finer/R3Stretcher.h @@ -93,6 +93,7 @@ class R3Stretcher void setExpectedInputDuration(size_t samples); void setMaxProcessSize(size_t samples); + size_t getProcessSizeLimit() const; void setDebugLevel(int level) { m_log.setDebugLevel(level); diff --git a/src/rubberband-c.cpp b/src/rubberband-c.cpp index 225edd03..e7fd1543 100644 --- a/src/rubberband-c.cpp +++ b/src/rubberband-c.cpp @@ -143,6 +143,11 @@ void rubberband_set_max_process_size(RubberBandState state, unsigned int samples state->m_s->setMaxProcessSize(samples); } +unsigned int rubberband_get_process_size_limit(RubberBandState state) +{ + return state->m_s->getProcessSizeLimit(); +} + void rubberband_set_key_frame_map(RubberBandState state, unsigned int keyframecount, unsigned int *from, unsigned int *to) { std::map kfm; diff --git a/src/test/TestStretcher.cpp b/src/test/TestStretcher.cpp index cbf3ae3c..6b2810e6 100644 --- a/src/test/TestStretcher.cpp +++ b/src/test/TestStretcher.cpp @@ -46,8 +46,10 @@ BOOST_AUTO_TEST_CASE(engine_version) { RubberBandStretcher s2(44100, 1, RubberBandStretcher::OptionEngineFaster); BOOST_TEST(s2.getEngineVersion() == 2); + BOOST_TEST(s2.getProcessSizeLimit() == 524288); RubberBandStretcher s3(44100, 1, RubberBandStretcher::OptionEngineFiner); BOOST_TEST(s3.getEngineVersion() == 3); + BOOST_TEST(s3.getProcessSizeLimit() == 524288); } BOOST_AUTO_TEST_CASE(sinusoid_unchanged_offline_faster) @@ -1006,7 +1008,7 @@ static void impulses_realtime(RubberBandStretcher::Options options, BOOST_TEST(peak1 > int(ceil(4640 * timeRatio))); BOOST_TEST(peak2 < int(ceil(9970 * timeRatio))); - BOOST_TEST(peak2 > int(ceil(9770 * timeRatio))); + BOOST_TEST(peak2 > int(ceil(9670 * timeRatio))); if (printDebug) { std::cout << "#sample\tV" << std::endl;